Bagaimana kami memilih protokol VPN dan menyiapkan server

Mengapa semua ini dan untuk apa?



Kami memiliki: 10 konfigurasi server paling sederhana di DigitalOcean, perangkat seluler iOS, server untuk mengumpulkan statistik, tidak ada pengalaman dalam menyiapkan server VPN, dan keinginan yang kuat untuk membuat layanan VPN yang cepat, andal, dan mudah digunakan yang akan dinikmati Nikmati. Bukan berarti semua ini mutlak diperlukan, tetapi jika kita sudah memulainya, maka kita perlu melakukan pendekatan serius.



Dalam artikel ini, saya akan menjelaskan secara singkat bagaimana kami memilih protokol VPN, bagaimana kami mengatur server dan bagaimana kami mengatur pengumpulan statistik dari setiap server VPN. Jangan mengandalkan petunjuk langkah demi langkah yang mendetail. Dalam artikel ini, saya akan memberikan kutipan dari file konfigurasi dengan komentar singkat.



Saya rasa di bidang TI Anda tidak akan lagi menemukan orang yang tidak tahu apa itu VPN dan mengapa Anda membutuhkannya.



Tetapi jika itu adalah tesis untuk menjelaskan mengapa orang modern membutuhkan VPN, maka hal seperti ini akan terjadi:



  • Jika Anda memiliki sumber daya internal (pribadi), aksesnya harus dibatasi dari Internet global.
  • Jika Anda perlu membuat koneksi aman antara dua jaringan.
  • Jika Anda perlu mengakses sumber daya yang, karena satu dan lain alasan, tidak tersedia dari negara Anda (lokasi Anda berubah relatif terhadap alamat IP Anda).


Dan poin yang tidak sepenuhnya jelas: kecepatan koneksi Internet bisa lebih tinggi melalui vpn, karena ISP Anda dapat mengirimkan lalu lintas Anda di sepanjang rute yang lebih pendek, yang berarti rute yang lebih optimal, karena itu, Anda bisa mendapatkan peningkatan kecepatan. Tetapi itu bisa bekerja ke arah yang berlawanan jika Anda memilih lokasi server yang tidak terlalu baik dibandingkan Anda (lebih lanjut tentang itu nanti).



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 .


?



Melalui trial and error, kami menemukan opsi yang dijelaskan dalam artikel, pertama-tama kami menganut prinsip "membuatnya lebih sederhana", tidak menemukan kembali sepeda kami sendiri dan menggunakan alat yang sudah jadi seperti Docker, FreeRadius. Ya, kemungkinan besar ada tempat untuk pengoptimalan, pengetatan kebijakan keamanan, otomatisasi. Tetapi opsi kami sangat cocok untuk penggunaan pribadi dan untuk digunakan di perusahaan kecil jika Anda perlu mengatur akses ke informasi pribadi (tertutup).




All Articles