Last active
December 13, 2023 14:58
-
-
Save lukeplausin/633bb03404f998caf033af04bdf9678c to your computer and use it in GitHub Desktop.
This script will configure a linux host to become available for inbound connections. It will install sshd and miniupnp (for port forwarding) and duck dns for dns registration.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This script assumes that you are using a router or device which uses NAT and support upnp, | |
# you are using ip4 and a debian based linux distro (this covers 90% of home networks and raspberry pi). | |
# Home routers often won't let you expose port 22, so the port is exposed and mapped with upnp. | |
# Copy the script to your computer, and then edit the variables at the top. | |
# Then run the script by typing "bash ./home_ssh_server.sh" into the terminal. | |
### Variables ### | |
# This is the public hostname which you will use to connect to your home server. | |
# Go to https://www.duckdns.org/domains and register a free account for external dns. | |
duck_hostname='my.dns.server' | |
duck_secret='MY_SECRET_KEY' | |
ssh_port_local="22" | |
ssh_port_external="2222" | |
### Commands ### | |
sudo apt-get update -y | |
sudo apt-get install -y sshd miniupnpc curl dig | |
# Disable password authentication on ssh service | |
# why: because it's a security risk | |
sudo sed -i "s/PasswordAuthentication.*/PasswordAuthentication no/g" /etc/ssh/sshd_config | |
# You will be able to log in with a PEM key | |
mkdir -p ~/.ssh/ | |
ssh-keygen -f ~/.ssh/my_keyfile -N "" | |
cat ~/.ssh/my_keyfile.pub >> ~/.ssh/authorized_keys | |
# Configure dns auto update with duckdns | |
mkdir -p /opt/duckdns | |
cat << EOF > /tmp/update_duckdns.sh | |
# This is the script which updates the external dns name in duck to the external IP address of your home router. | |
duck_hostname=$duck_hostname | |
duck_secret=$duck_secret | |
ssh_port_local=$ssh_port_local | |
ssh_port_external=$ssh_port_external | |
# Set up upnp port forwarding on local network.. | |
upnp_out=\$(upnpc -r \$ssh_port_local \$ssh_port_external tcp) | |
if [ $? ]; then | |
echo "\$upnp_out" | |
fi | |
# Update external dns name to point to external IP address of router (if it has changed) | |
external_ip=\$(echo "\$upnp_out" | grep ExternalIPAddr | cut -d '=' -f 2) | |
old_external_ip=\$(cat /opt/duckdns/last_ip.txt) | |
if [ \$external_ip != \$old_external_ip ]; then | |
url="https://www.duckdns.org/update?domains=\$duck_hostname&token=\$duck_secret&ip=\$external_ip" | |
echo \$url | curl -k -o /var/log/duckdns.log -K - | |
echo \$external_ip > /opt/duckdns/last_ip.txt | |
fi | |
EOF | |
sudo mv /tmp/update_duckdns.sh /opt/duckdns/update_duckdns.sh | |
sudo chown root:root /opt/duckdns/update_duckdns.sh | |
sudo chmod 755 /opt/duckdns/update_duckdns.sh | |
# Set up the duck update script up to run on a schedule | |
cat << EOF > /tmp/sshd_server_network_update | |
# This crontab file updates networking to keep your home server available for SSH over the internet | |
SHELL=/bin/sh | |
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin | |
*/5 * * * * root /opt/duckdns/update_duckdns.sh > /var/log/home_ssh_server_networking.log | |
EOF | |
sudo mv /tmp/sshd_server_network_update /etc/cron.d/sshd_server_network_update | |
sudo chown root:root /etc/cron.d/sshd_server_network_update | |
sudo chmod 755 /etc/cron.d/sshd_server_network_update | |
# Advice for the end user... | |
echo "Your private SSH key which you will use to log in is saved in $HOME/.ssh/my_keyfile" | |
echo "Don't forget to copy your private SSH key to any devices which you will want to connect from." | |
echo "" | |
echo "To log into your home SSH server, use this command:" | |
echo " ssh -i ~/.ssh/my_keyfile `whoami`@$duck_hostname.duckdns.org:$ssh_port_external" | |
echo "" | |
echo "" | |
echo "For convenience, you might want to add these lines to your ssh config file (~/.ssh/config)" | |
echo "so that you can simply run 'ssh homeserver' to connect." | |
echo "" | |
echo "Host homeserver" | |
echo " Host $duck_hostname.duckdns.org" | |
echo " Port $ssh_port_external" | |
echo " User `whoami`" | |
echo " IdentityFile ~/.ssh/my_keyfile" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment