This is just how I setup the current NX main node. As everything
when dealing with system administration and network setup, there
are plenty of other ways to do it, and this describes only my
precise setup. However, if you think of ideas to improve
functionality or ease of use, please let me know, I'll be happy
to place your contribution here.
Initial setup
Straight to the real thing... I assume that you want to setup a
VPN server, allowing PPP/SSH connections. The connections will
be setup as described in the NX hookup
instructions. Basically, every client will have to supply
to you (the server) a SSH RSA public key, that you will add
to a file, along with the VPN IP address of the client. The
big advantage of this setup is that you only need to add a line
per client in a file, and you're done.
-
Create a user, named for instance "vpn". If you plan
to run many separate VPN with various "classes" of users, you
can create, say, "vpnfoo" and "vpnbar", or "foo" and "bar" in
a "vpn" group, as you like.
-
Grab the vpnwrapper script, and put
it somewhere - I suggest /usr/local/bin, or ~vpn. It should
be owned by root, and in mode 755 (the vpn user should not
be able to modify it).
-
Change the shell for the vpn user to the vpnwrapper. You
can do that with chsh, or edit your passwd file (vipw is
your friend).
-
While we're modifying passwd entries, change the password
field of the vpn user to a star ("*"), so this user won't
be able to login thru password-based authentication.
That leaves us only with SSH key-based authentication.
If your system provides rhosts-based access, check that
it can't work for vpn user.
-
You should have a SSH daemon operating on your server.
If not, install it now. RSA key authentication should
be enabled (it's the default, so you should not have
to mess with a lot of things...)
-
Create the directory : ~vpn/.ssh ; and put an empty file
named authorized_keys in it.
-
You should now install sudo. You can use something
else, but then, the details are up to you. I used
a standard sudo, and put the following line in sudoers
file (you generally edit sudoers with the visudo command) :
vpn ALL=(ALL) NOPASSWD: /usr/sbin/pppd
The goal of this is to allow the vpn user to start
the pppd process as root, thus allowing it to specify
any parameter it likes (if you use a pppd SUID, you
can't specify arbitrary parameters and need extra
per-client configuration).
-
You're done.
-
Well, I lied. You should right now choose an IP addressing
plan ; for instance, I decided that the IP address of the
endpoint would be 192.168.0.179 (why? because I use a
pseudo-anycast setup, where services are located on the
192.168.0.0/24 subnet, and 179 is the port used by BGP).
-
You may want to run some kind of routing daemon. I recommend
Zebra or MRTD, personnally I use Zebra. Configuring Zebra
is out of the scope of this document, but if there is
sufficient demand, I'll provide explanations about how
to setup Zebra on a VPN server node. In the meanwhile,
you can consult how to setup Zebra on the client side
(here), as it is not so different.
Adding clients
Normally, clients should send you a SSH RSA key (looks like : "1024 33
2103948298LotsOfNumbers20349839"), a symbolic name (that you will use
to discriminate connections), and the IP address they want. If you
approve their choice, just add a line in ~vpn/.ssh/authorized_keys,
like the following one :
command="symbolicname lo.ca.l.ip:re.mo.te.ip extraoptions" 1024 35 234983TheirPublicKey230498"
You can skip the extraoptions part ; I never use it but you could put "debug"
here : these options will be passed to the pppd program.
What does vpnwrapper do ?
The first part just checks that it's called as a user login shell :
#!/bin/sh
function syntax () {
echo 'Syntax: '"$0"' -c [extraparams]'
exit 1
}
[ "$1" = "-c" ] || syntax
Then, it extracts various parameters (as they will be given
by the command="symbolicname localip:remoteip extraoptions" stanza
in authorized_keys) :
PARAMS=($2)
NAME="${PARAMS[0]}"
IP="${PARAMS[1]}"
PARAMS[0]=
PARAMS[1]=
Next, it checks the format of local and remote IP address.
It's not a bulletproof check, but it will catch some typos
(but not 123.456.789.0 addresses) :
DIGIT='[0-9]'
BYTE=$DIGIT?$DIGIT?$DIGIT
IPA=$BYTE\.$BYTE\.$BYTE\.$BYTE
echo "$IP" | grep -Eq "$IPA:$IPA" || syntax
We do a bit of logging. No syslog or whatever, but this
logs the date, the hostname (for log consolidation), the
PID (to track pppd messages in syslog), the name of the
client, the extra parameters. Note that we could also
use a more elaborated setup where we would log the
deconnection of clients, to calculate connection times.
But I did not need this feature so I did not implement it.
echo "$(date) | $HOSTNAME | $$ | $NAME | $PARAMS" >> ~/vpn.log
Finally, we start pppd. Notice the linkname option, which
allows you to track pppd processes in /var/run by the
name of the client instead of requiring you a lookup
to the log or whatever.
exec sudo /usr/sbin/pppd noauth linkname "$NAME" "$IP" ${PARAMS[@]}
Please note that there is no locking mechanism or whatever,
so if a client connects twice using the same key, that won't
kill the first connection whatsoever. But if a connection
crashes, LCP wiil terminate it after rougly 30 seconds with
pppd default parameters.
How do I setup DNS?
This is out of the scope of this document. If there is sufficient
demand, I'll explain how to setup a "rogue" TLD, using BIND
and stubs zones.
Troubleshooting
Just create a SSH RSA key, add it to the authorized_keys
file (with some command="whatever 192.168.0.179:192.168.0.180" thekeyitself),
and try to login using the key (ssh -i fileholdingthekey -t vpn@localhost).
You should get the beginning of the LCP negociations, which usually goes
}#!}!}!} }4}"}&} } } } }%}&}/H}=}'}"}(}"~~~~~~~~
or the like.
If that does not work, try running a debug server : "sshd -dp 222",
and connect to it using "-p222" to the client SSH command line.
If that still does not help, feel free to contact me. I don't grant
a quick response, but I'll be happy to improve this document.
First release of this document ; orthographic corrections
and comments are welcome !
skaya@enix.org