Comment nous avons choisi le protocole VPN et configuré le serveur

Pourquoi tout cela et pourquoi?



Nous avions: 10 configurations de serveur les plus simples sur DigitalOcean, appareils mobiles iOS, un serveur pour la collecte de statistiques, aucune expérience dans la configuration de serveurs VPN et une volonté indomptable de créer un service VPN rapide, fiable et facile à utiliser qui plaira prendre plaisir. Non pas que tout cela était absolument nécessaire, mais si nous avons déjà commencé, nous devons aborder la question sérieusement.



Dans cet article, je décrirai brièvement comment nous avons choisi le protocole VPN, comment nous avons configuré le serveur et comment nous avons organisé la collecte des statistiques de chaque serveur VPN. Ne vous fiez pas aux instructions détaillées étape par étape. Dans l'article, je fournirai des extraits des fichiers de configuration avec de brefs commentaires.



Je pense que dans la sphère informatique, vous ne trouverez plus une personne qui ne saurait pas ce qu'est un VPN et pourquoi vous en avez besoin.



Mais si c'est une thèse pour expliquer pourquoi une personne moderne a besoin d'un VPN, alors quelque chose comme ça se produira:



  • Si vous disposez de ressources internes (privées) dont l'accès doit être limité à partir de l'Internet mondial.
  • Si vous devez établir une connexion sécurisée entre deux réseaux.
  • Si vous avez besoin d'accéder à des ressources qui, pour une raison ou une autre, ne sont pas disponibles dans votre pays (votre emplacement change en fonction de votre adresse IP).


Et le point pas tout à fait évident: la vitesse de la connexion Internet peut être plus élevée via VPN, car votre FAI peut envoyer votre trafic sur un itinéraire plus court, ce qui signifie un itinéraire plus optimal, grâce à cela, vous pouvez obtenir une augmentation de la vitesse. Mais cela peut fonctionner dans la direction opposée si vous choisissez un emplacement de serveur pas très bon par rapport à vous (nous en reparlerons plus tard).



VPN-



VPN- .



.



, :



  • .
  • .


+ , .



PPTP (Point-To-Point Tunneling Protocol)



VPN , Microsoft. - , . Microsoft L2TP SSTP PPTP.



, .



L2TP/IPSec



PPTP, . , -, .. .

L2TP/IPsec , . : , , VPN-.



.. , , , .



IKEv2/IPSec



Microsoft Cisco, (, OpenIKEv2, Openswan strongSwan).



Mobility and Multi-homing Protocol (MOBIKE), .



IKEv2 , WiFi .



IKEv2 .



, .. Mobility and Multi-homing Protocol .



OpenVPN



OpenVPN Technologies.



, .

OpenVPN . , TCP UPD, . VPN .



OpenVPN, , .



, , , - , .



Wireguard



VPN. IPSec OpenVPN, , , .



Unix , .. Unix. .



, , .



.



IKEv2/IPSe, :



  • Mobility and Multi-homing Protocol (MOBIKE).
  • .
  • .
  • .


.



VPN-



, , () ().



— , .. , ( ), .., , - .



- , digitalocean , 1 Gb 25 Gb .



, - VPN- .



:



  • Docker + docker-compose.
  • strongswan — IPSec .
  • Let's Encrypt — .
  • Radius — .


Docker , vpn-.



Docker.file ( )



FROM alpine:latest #      alpine-linux

...
# strongSwan Version
ARG SS_VERSION="https://download.strongswan.org/strongswan-5.8.2.tar.gz" #   ,        .

...

COPY ./run.sh /run.sh
COPY ./adduser.sh /adduser.sh
COPY ./rmuser.sh /rmuser.sh

RUN chmod 755 /run.sh /adduser.sh /rmuser.sh

VOLUME ["/usr/local/etc/ipsec.secrets"]

EXPOSE 500:500/udp 4500:4500/udp

CMD ["/run.sh"]


adduser.sh, rmuser.sh .



adduser.sh



#!/bin/sh

VPN_USER="$1"

if [ -z "$VPN_USER" ]; then
  echo "Usage: $0 username" >&2
  echo "Example: $0 jordi" >&2
  exit 1
fi

case "$VPN_USER" in
  *[\\\"\']*)
    echo "VPN credentials must not contain any of these characters: \\ \" '" >&2
    exit 1
    ;;
esac

VPN_PASSWORD="$(openssl rand -base64 9)" #   
HOST="$(printenv VPNHOST)"

echo "Password for user is: $VPN_PASSWORD"
echo $VPN_USER : EAP \"$VPN_PASSWORD\">> /usr/local/etc/ipsec.secrets #        /usr/local/etc/ipsec.secrets

ipsec rereadsecrets


rmuser.sh



#!/bin/sh

VPN_USER="$1"

if [ -z "$VPN_USER" ]; then
  echo "Usage: $0 username" >&2
  echo "Example: $0 jordi" >&2
  exit 1
fi

cp /usr/local/etc/ipsec.secrets /usr/local/etc/ipsec.secrets.bak
sed "/$VPN_USER :/d" /usr/local/etc/ipsec.secrets.bak > /usr/local/etc/ipsec.secrets #        /usr/local/etc/ipsec.secrets

ipsec rereadsecrets


ipsec.secrets.



:



run.sh



#!/bin/bash

VPNIPPOOL="10.15.1.0/24" #       IP  ,     VPN-.
LEFT_ID=${VPNHOST}       #   vpn-

sysctl net.ipv4.ip_forward=1
sysctl net.ipv6.conf.all.forwarding=1
sysctl net.ipv6.conf.eth0.proxy_ndp=1

if [ ! -z "$DNS_SERVERS" ] ; then #    DNS ,     vpn .
DNS=$DNS_SERVERS
else
DNS="1.1.1.1,8.8.8.8"
fi

if [ ! -z "$SPEED_LIMIT" ] ; then #  ,     ""  ,       .
tc qdisc add dev eth0 handle 1: ingress
tc filter add dev eth0 parent 1: protocol ip prio 1 u32 match ip src 0.0.0.0/0 police rate ${SPEED_LIMIT}mbit burst 10k drop flowid :1
tc qdisc add dev eth0 root tbf rate ${SPEED_LIMIT}mbit latency 25ms burst 10k
fi

iptables -t nat -A POSTROUTING -s ${VPNIPPOOL} -o eth0 -m policy --dir out --pol ipsec -j ACCEPT
iptables -t nat -A POSTROUTING -s ${VPNIPPOOL} -o eth0 -j MASQUERADE

iptables -L

#     
if [[ ! -f "/usr/local/etc/ipsec.d/certs/fullchain.pem" && ! -f "/usr/local/etc/ipsec.d/private/privkey.pem" ]] ; then
    certbot certonly --standalone --preferred-challenges http --agree-tos --no-eff-email --email ${LEEMAIL} -d ${VPNHOST}
    cp /etc/letsencrypt/live/${VPNHOST}/fullchain.pem /usr/local/etc/ipsec.d/certs
    cp /etc/letsencrypt/live/${VPNHOST}/privkey.pem /usr/local/etc/ipsec.d/private
    cp /etc/letsencrypt/live/${VPNHOST}/chain.pem /usr/local/etc/ipsec.d/cacerts
fi

rm -f /var/run/starter.charon.pid

#   ipsec 
if [ -f "/usr/local/etc/ipsec.conf" ]; then
rm /usr/local/etc/ipsec.conf
cat >> /usr/local/etc/ipsec.conf <<EOF
config setup
    charondebug="ike 1, knl 1, cfg 1"
    uniqueids=never
    conn ikev2-vpn
    ...

    eap_identity=%identity
EOF
fi

if [ ! -f "/usr/local/etc/ipsec.secrets" ]; then
cat > /usr/local/etc/ipsec.secrets <<EOF
: RSA privkey.pem
EOF
fi

.....
EOF
fi
sysctl -p

ipsec start --nofork


, docker-compose:



version: '3'

services:
  vpn:
    build: .
    container_name: ikev2-vpn-server
    privileged: true
    volumes:
      - './data/certs/certs:/usr/local/etc/ipsec.d/certs'
      - './data/certs/private:/usr/local/etc/ipsec.d/private'
      - './data/certs/cacerts:/usr/local/etc/ipsec.d/cacerts'
      - './data/etc/ipsec.d/ipsec.secrets:/usr/local/etc/ipsec.secrets'
    env_file:
      - .env
    ports:
      - '500:500/udp'
      - '4500:4500/udp'
      - '80:80'
    depends_on:
      - radius
    links:
      - radius
    networks:
      - backend

  radius:
    image: 'freeradius/freeradius-server:latest'
    container_name: freeradius-server
    volumes:
      - './freeradius/clients.conf:/etc/raddb/clients.conf'
      - './freeradius/mods-enabled/rest:/etc/raddb/mods-enabled/rest'
      - './freeradius/sites-enabled/default:/etc/raddb/sites-enabled/default'
    env_file:
      - .env
    command: radiusd -X
    networks:
      - backend
networks:
  backend:
    ipam:
      config:
        - subnet: 10.0.0.0/24


volume , .



, , Let's Encrypt.



.env , :



VPNHOST=vpn.vpn.com #   vpn-
LEEMAIL=admin@admin.com #  ,       Let's Encrypt
SPEED_LIMIT=20 #  ,       mbit
DNS_SERVERS= #      DNS 
RADIUS_SERVER= #  radius ,      radius
RADIUS_SERVER_SECRET= #  ,       radius 
REMOTE_SERVER= #     endpoint,      radius ,    .


docker-compose up -d, vpn-, radius ( ).





VPN-



, , . ipsec, , - , .



, , FreeRadius , ipsec .



FreeRadius , .

radius ipsec:



FreeRADIUS



if [[ ! -z "$RADIUS_SERVER" && ! -z "$RADIUS_SERVER_SECRET" ]]; then
rm /usr/local/etc/strongswan.d/charon/eap-radius.conf
cat >> /usr/local/etc/strongswan.d/charon/eap-radius.conf <<EOF
eap-radius {
    accounting = yes #  , ipsec        /,        
    accounting_close_on_timeout = no
    accounting_interval = 300 #    radius     .
    close_all_on_timeout = no
    load = yes
    nas_identifier = $VPNHOST

    # Section to specify multiple RADIUS servers.
    servers {
        primary {
            address = $RADIUS_SERVER
            secret = $RADIUS_SERVER_SECRET
            auth_port = 1812   # default
            acct_port = 1813   # default
        }
    }
}


endpoint, rest. /etc/raddb/mods-enabled/rest accounting, - :



accounting {
    uri = "${..connect_uri}/vpn_sessions/%{Acct-Session-Id}-%{Acct-Unique-Session-ID}"
method = 'post'
tls = ${..tls}
body = json
data = '{ "username": "%{User-Name}", "nas_port": "%{NAS-Port}", "nas_ip_address": "%{NAS-IP-Address}", "framed_ip_address": "%{Framed-IP-Address}", "framed_ipv6_prefix": "%{Framed-IPv6-Prefix}", "nas_identifier": "%{NAS-Identifier}", "airespace_wlan_id": "%{Airespace-Wlan-Id}", "acct_session_id": "%{Acct-Session-Id}", "nas_port_type": "%{NAS-Port-Type}", "cisco_avpair": "%{Cisco-AVPair}", "acct_authentic": "%{Acct-Authentic}", "tunnel_type": "%{Tunnel-Type}", "tunnel_medium_type": "%{Tunnel-Medium-Type}", "tunnel_private_group_id": "%{Tunnel-Private-Group-Id}", "event_timestamp": "%{Event-Timestamp}", "acct_status_type": "%{Acct-Status-Type}", "acct_input_octets": "%{Acct-Input-Octets}", "acct_input_gigawords": "%{Acct-Input-Gigawords}", "acct_output_octets": "%{Acct-Output-Octets}", "acct_output_gigawords": "%{Acct-Output-Gigawords}", "acct_input_packets": "%{Acct-Input-Packets}", "acct_output_packets": "%{Acct-Output-Packets}", "acct_terminate_cause": "%{Acct-Terminate-Cause}", "acct_session_time": "%{Acct-Session-Time}", "acct_delay_time": "%{Acct-Delay-Time}", "calling_station_id": "%{Calling-Station-Id}", "called_station_id": "%{Called-Station-Id}"}'

 }


.



VPN , , Apple , , , Let's Encrypt.



?



  • radius , VPN.
  • , VPN-.


VPN-?



  • radius.
  • .
  • , .
  • health-check .


?



Par essais et erreurs, nous avons proposé l'option décrite dans l'article, tout d'abord nous avons adhéré au principe de «simplifier les choses», n'avons pas réinventé nos propres vélos et utilisé des outils prêts à l'emploi comme Docker, FreeRadius. Oui, il y a probablement une place pour l'optimisation, le renforcement des politiques de sécurité, l'automatisation. Mais notre option est parfaite pour un usage personnel et pour une utilisation dans les petites entreprises si vous avez besoin d'organiser l'accès à des informations privées (fermées).




All Articles