Skip to content

Instantly share code, notes, and snippets.

@ivanstepanovftw
Last active September 6, 2019 21:43
Show Gist options
  • Save ivanstepanovftw/7122a5a07ba71e593f6a1085fd1ad889 to your computer and use it in GitHub Desktop.
Save ivanstepanovftw/7122a5a07ba71e593f6a1085fd1ad889 to your computer and use it in GitHub Desktop.
x11vnc over passwordless SSH with Google Authenticator on Arch Linux

x11vnc over passwordless SSH with Google Authenticator on Arch Linux

How auth will look after configuration:

Enter your private key password: 
User: user
< client sends his public key to server, signed by client's private key (correct me if I am wrong) >
2FA code: 123123
user's password: 

[user@pc ~]$ 

Q: Why it is so complicated?
A: You can crack your user password via SSH in just some minutes/days while you are on vacation. To prevent this, use Key-based authentication (you will be dead already before it will be cracked). And harden it with 2FA in case someone is got your Private Key and its password (e.g. your manager at the work).

In case you do not trust client PC:

  • use KeePassXC, disable bidirectional clipboard;
  • do not use untrusted PC.

Contents

Table of contents generated with markdown-toc

Server-side setup

Pre-requirements

Packages required: x11vnc, openssh, libpam-google-authenticator, qrencode (optional).

Dynamic DNS

For this example PC username is user, hostname is pc, public IP is ivanstepanovftw.ddns.net. Setup DDNS (e.g. No-IP) on your router (or PC) if you have dynamic IP.

Open public port

Public ports:

  • SSH is 443 (80 in case your Network Administrator blocks 443)

Local ports:

  • x11vnc is 5901 (because some Windows VNC clients does not allow 'loopback connection')

Open these ports on your router/firewall and restart router:

Name Protocol Port
SSH TCP 443

SSH daemon

Enabling daemon

Enable sshd (make it launch at start):

sudo systemctl enable sshd

Configuring daemon

Further reading: OpenSSH (ArchWiki)
Further reading: Google Authenticator (ArchWiki)

Edit /etc/ssh/sshd_config like:

GatewayPorts yes  # remote port forwarding (for x11vnc)
PermitEmptyPasswords no
PasswordAuthentication no
ChallengeResponseAuthentication yes
UsePAM yes
AuthenticationMethods publickey,keyboard-interactive

Edit /etc/pam.d/sshd like:

 auth            required        pam_google_authenticator.so
 auth            include         system-remote-login
 account         include         system-remote-login
 password        include         system-remote-login
 session         include         system-remote-login

Generating 2FA secret key

Further reading: Generating a secret key file (ArchWiki)

Generate .google_authenticator file:

google-authenticator

Scan QR Barcode with Google Authenticator (Google Play/App Store)

Start/restart SSH daemon

Restart sshd to apply settings:

sudo systemctl restart sshd

Client-side setup

SSH setup

Linux (OpenSSH)

1. Generate Key
ssh-keygen -t rsa -b 4096 -C "$(whoami)@$(hostname) $(date '+%x %X')"
2. Export Public Key to your PC

Use ssh-copy-id. Set PasswordAuthentication yes in /etc/ssh/sshd_config for this step.

ssh-copy-id user@pc -p 443

---or---

Copy your Public Key:

cat ~/.ssh/id_rsa.pub

Then read Sending client Public Key securely

3. Connect
ssh -p 443 user@pc

Android (JuiceSSH)

1. Generate Key
  • Identities -> New Identity:
  • Username: user (your username at your PC)
  • Private Key: Generate -> Key Format: RSA -> OK
  • OK
2. Export Public Key to your PC
# Server-side
mkdir -p ~/.ssh
touch ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDSkT3A1j89... JuiceSSH" >> ~/.ssh/authorized_keys

---or---

Use JuiceSSH pro features. Set PasswordAuthentication yes in /etc/ssh/sshd_config for this step.

3. Connect
  • Connections -> New Connection
  • Type: SSH
  • Address: ivanstepanovftw.ddns.net (your static IP or DDNS address)
  • Identity: user (your identity you created before)
  • Port: 443
  • OK

Windows (PuTTY)

Or just watch this video at 2x speed: https://youtu.be/2nkAQ9M6ZF8

1. Generate Key
  • Launch pyttygen.exe
  • Generate
  • Add Private Key password
  • Save PuTTY Key file to Documents/id_rsa.ppk for example
  • Copy and paste Private Key in notepad, because it is malformatted in the .ppk file
  • Launch PuTTY Key file id_rsa.ppk via pagent.exe, enter Private Key password if prompted
2. Export Public Key to your PC
  • Read Sending client Public Key securely. Paste Private Key to ~/.ssh/authorized_keys:
    # Server-side
    mkdir -p ~/.ssh
    touch ~/.ssh/authorized_keys
    chmod 700 ~/.ssh
    chmod 600 ~/.ssh/authorized_keys
    echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDSkT3A1j89... rsa-key-20190818" >> ~/.ssh/authorized_keys
3. Connect to SSH
  • Launch putty.exe
  • Go to: Connection -> SSH -> Auth
    • Private key file for authentication: id_rsa.ppk
  • Go to: Connection -> SSH -> Auth -> Tunnels
    • Source port: 5901
    • Destination: localhost:5901
    • Add
  • Go to: Session
    • Host Name (or IP address): ivanstepanovftw.ddns.net
    • Port: 443
    • Saved Sessions: PC -> Save (now you are able to Load your credential later)
    • Press Open button, type user as login

x11vnc over SSH

Further reading: SSH Tunneling (ssh.com)

VNC password

Further reading: How to secure VNC with SSH (mit.edu)

You may skip this step, because VNC password is formal.

Setup password for VNC (see also: man vncpasswd):

x11vnc -storepasswd

Password will be stored at /home/user/.vnc/passwd with 600 permissions (-rw-------). VNC password is not encrypted, so do not use VNC without encryption over internet.

Run SSH Port Forwarding and x11vnc

Further reading: X11vnc (ArchWiki)
Further reading: x11vnc --help | less

Start ssh local port forwarding (-Local, not -Remote):

ssh -x -e none -L 5901:localhost:5900 ivanstepanovftw.ddns.net -p 443

Launch x11vnc (add -usepw if you wanted to use formal VNC password):

x11vnc -localhost -rfbport 5900 -rfbportv6 5900 -display :0 -forever

VNC client

Android (bVNC)

  • Connection Type: Secure VNC over SSH
  • SSH Server: ivanstepanovftw.ddns.net
  • SSH Port: 443
  • SSH Username: user
  • Select Use Key
  • Manage Key -> Generate new key or import
  • VNC Server: localhost
  • VNC Port: 5901
  • VNC Password: your VNC Password if -usepw used

Windows (PuTTY and RealVNC VNC Viewer)

Start PuTTY, connect to server, then open VNC Client:

  • VNC server: localhost:5901
  • Connect

Tips

Get local IP

ip addr

Sending client Public Key securely

If you sending Public Key to person, that you will never see, your Public Key can be MiTM-ed by your provider or SORM (Wikipedia), over non-secure way (for example, via HTTP or via untrusted sites like https://vk.com). In that case you can detect MiTM only by verifying your Public Key or Public Key Fingerprint via secure method.

So, best practice is meeting with an another person and providing him the Public Key or Public Key Fingerprint.

Send your Public Key via any secure and trusted method, e.g. via Telegram, Gmail, any non-centralized Blockchain or even USB.

Always verify fingerprint if you connecting first time to your PC or after refreshing server Public Key (you will be notified like that: WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!).

Fingerprint verification

Execute on server:

for a in /etc/ssh/*.pub; do sudo ssh-keygen -E md5 -l -f ${a}; done

Author

Ivan Stepanov [email protected]

TODO

  • wrap ssh port forwarding and x11vnc in a service
  • VNC client for iOS, macOS and linux
  • some links to download are missing
  • VNC speedup
  • Regenerating /etc/ssh keys
  • Add chromium SSH client extension
  • SSH and HTTPS port mixing with sslh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment