OpenVPN, tentang yang Anda tahu sangat sedikit

OpenVPN, berapa banyak kata ini. Server VPN sumber terbuka multi-platform, sangat dapat disesuaikan, gratis, yang sebenarnya merupakan standar defacto untuk mengatur akses ke jaringan internal perusahaan. Sebagian besar administrator menggunakannya dengan pengaturan default atau dengan konfigurasi tipikal yang banyak dijelaskan dalam CARA-TO yang berbeda. Tetapi apakah OpenVPN sangat sederhana seperti yang terlihat pada pandangan pertama? Pada artikel ini, kami akan mempertimbangkan mekanisme internal OpenVPN, tersembunyi dari mata, yang secara drastis mengubah ide kemampuannya.


Server OpenVPN didistribusikan dalam bentuk kode sumber atau paket terkompilasi yang siap dipasang untuk berbagai sistem operasi. OpenSSL digunakan sebagai perpustakaan yang menyediakan enkripsi.


Sebagian besar konfigurasi untuk menghubungkan klien ke server, serta antar server, melibatkan penggunaan sekelompok kunci privat atau privat / publik untuk memastikan keamanan lalu lintas internal. Untuk jaringan perusahaan dalam mode MultiPoint-To-SinglePoint, biasanya digunakan pusat sertifikasi PKI sendiri, yang mudah dibangun menggunakan easy-rsa atau berbasis XCA . Untuk komunikasi antar server point-to-point, konfigurasi shared-key terutama digunakan. Ingat kembali mekanisme dan kapabilitas dasar yang terkenal.


Mekanisme dan kemampuan utama


  • Otentikasi Sertifikat


    Sejumlah besar dokumentasi telah ditulis tentang hal itu. Intinya sederhana. Otoritas sertifikat sedang dibuat yang mengeluarkan sertifikat pengguna. Dengan bantuan kontrol otoritas sertifikasi disediakan untuk menghubungkan pengguna ke server OpenVPN. Ketika sertifikat kedaluwarsa atau dicabut, akses pengguna diblokir. Kunci pribadi dengan kata sandi yang ditetapkan pada mereka, dikeluarkan bersama dengan sertifikat, memberikan keamanan terhadap koneksi yang tidak sah ke sumber daya internal.


  • Kunci point-to-point pribadi


    Dari sudut pandang menghubungkan hanya satu pengguna / server ke sumber daya perusahaan, skema dengan kunci pribadi digunakan. Kunci dihasilkan di salah satu host, yang dibagi antara server dan klien.



Dalam semua kasus koneksi untuk keamanan jabat tangan "jabat tangan" antara klien dan server protokol Diffie-Hellmann digunakan.


  • Otentikasi pengguna eksternal


    Untuk menyederhanakan kontrol atas koneksi pengguna, alih-alih skema dengan PKI sendiri, Anda dapat menggunakan skema dengan otentikasi pengguna eksternal dengan login / kata sandi . Skema ini nyaman untuk mengautentikasi pengguna dengan, katakanlah, login / kata sandi domain. Untuk terhubung ke server, sertifikat server dan kunci penandatanganan paket KEAMANAN OPENVPN ditambahkan ke file konfigurasi klien.
    contoh konfigurasi klien


    dev tun proto udp #  IP  OpenVPN remote 172.16.111.166 # Port  port 1200 client resolv-retry infinite tls-client key-direction 1 auth SHA1 cipher BF-CBC #comp-lzo persist-key persist-tun # auth-user-pass c:/temp/pass.txt # # just create a file with name pass.txt # and put to it two lines # ------------- #username #password # ------------- #auth-user-pass verb 3 <ca> -----BEGIN CERTIFICATE----- MIIE5jCCA86gAwIBAgIJAOt3kFH7PxA0MA0GCSqGSIb3DQEBCwUAMIGjMQswCQYD .... -----END CERTIFICATE----- </ca> <tls-auth> -----BEGIN OpenVPN Static key V1----- 83ddd29fa82212f3059d85a41490134c .... a4f2c7df3a22364a49093bca102dedeb -----END OpenVPN Static key V1----- </tls-auth> 

    Bagian dari konfigurasi server untuk otentikasi klien melalui file
    Menggunakan metode otentikasi alternatif


     verify-client-cert none #client-cert-not-required username-as-common-name tls-server tls-auth /usr/local/etc/openvpn/ssl/tlsauth.key key-direction 0 tls-timeout 120 auth SHA1 cipher BF-CBC auth-user-pass-verify /usr/local/etc/openvpn/auth/auth-static-file.pl via-file 

    Skema ini nyaman, tetapi sangat tidak aman.


  • PAM


    Untuk meningkatkan keamanan, Anda dapat menggunakan plug-in yang menyediakan verifikasi login / kata sandi di sistem eksternal. Metode yang paling umum adalah sistem PAM (Modul Otentikasi Pluggable).
    Tambahkan baris ke file konfigurasi OpenVPN


     plugin /usr/share/openvpn/plugin/lib/openvpn-auth-pam.so login 

  • Routing


    Karena tugas utama server adalah untuk menyediakan akses pengguna / server jarak jauh ke sumber daya internal, server memungkinkan Anda untuk menentukan perutean statis dari klien ke server dan dari server ke klien. Dari sudut pandang akses klien ke sumber daya internal, server menggunakan DHCP dan arahan "rute" atau "rute push" memungkinkan Anda untuk mentransfer rute jaringan internal ke klien. Untuk memberi tahu server itu sendiri tentang jaringan jarak jauh di sisi klien, "client config dir" (ccd) digunakan, suatu mekanisme yang memungkinkan menggunakan arahan "iroute" untuk menggambarkan daftar jaringan internal klien yang harus ada dalam tabel perutean server untuk mengirim lalu lintas transit ke mereka.



Pada akhir fitur "biasa" ini banyak digunakan dan kustomisasi lokal untuk setiap kasus tertentu dimulai.


Fitur OpenVPN Tambahan


Pertimbangkan fitur tambahan OpenVPN, yang mungkin pernah didengar seseorang, tetapi dalam kenyataannya belum melihat atau menggunakan.


  • Keamanan Jaringan / Penyaringan Paket


    Karena OpenVPN merutekan traffic, ia memiliki dua mode operasi reguler yang saling eksklusif. Mode pertama adalah routing di dalam server OpenVPN, mode kedua adalah routing nuklir antar-antarmuka. Dalam kasus pertama, OpenVPN bertanggung jawab untuk mengganti dan memfilter paket antara klien / jaringan, dalam kasus kedua, semua filter paket sistem yang didukung pada host (pf, iptables, dll).
    Hanya sedikit orang yang tahu bahwa OpenVPN memiliki filter paket bawaan yang memungkinkan Anda mengizinkan atau mengisolasi koneksi antara pengguna dan jaringan.
    Ya, ya Anda membacanya dengan benar. OpenVPN memiliki filter paket bawaan. Kemampuan untuk menyaring lalu lintas diimplementasikan kembali pada tahun 2010 .
    Filter paket OpenVPN dikendalikan baik melalui antarmuka manajemen atau melalui plug-in yang terhubung ke OpenVPN.
    Aturan lalu lintas dikelola melalui file. Format file sederhana.


     [CLIENTS DROP|ACCEPT] {+|-}common_name1 {+|-}common_name2 . . . [SUBNETS DROP|ACCEPT] {+|-}subnet1 {+|-}subnet2 . . . [END] 

    Arahan blokir (ACCEPT / DENY) menetapkan tindakan default untuk semua klien yang tidak ditentukan di dalam blokir.
    Misalnya, file untuk klien pengguna2


     [CLIENTS DROP] +user1 [SUBNETS DROP] [END] 

    akan memblokir lalu lintas ke semua pengguna dan jaringan, tetapi mengizinkan lalu lintas ke sisi client1. Jika user1 tidak secara eksplisit menggambarkan izin untuk mentransfer lalu lintas ke user2, maka lalu lintas akan pergi hanya dalam satu arah user2-> user1.



Atau contoh lain.
Nonaktifkan semuanya kecuali akses antara pengguna dan server DNS yang terletak di jaringan lokal dan sirkuit tes di jaringan 192.168.0.0/24


 [CLIENTS DROP] +user1 +user2 [SUBNETS DROP] +10.150.0.1 +10.150.1.1 +192.168.0.0/24 [END] 

Mekanisme penyaringan diaktifkan melalui file konfigurasi, atau saat menghubungkan plugin yang "mengatur" bendera "OPENVPN_PLUGIN_ENABLE_PF".
Kami akan membahas peluang ini nanti.
Mode kedua dari traffic filtering adalah filter paket yang dibangun ke dalam sistem. Untuk mengaktifkannya, konfigurasi seharusnya tidak memiliki arahan "klien-ke-klien". Dari sudut pandang mengotomatiskan on / off dari aturan yang diperlukan saat menghubungkan / memutuskan klien, akan lebih mudah untuk menggunakan sisipan terpisah ke dalam daftar aturan, diimplementasikan baik melalui RANTAI di Iptables (Linux) atau di Jangkar di PF (FreeBSD). Aktivasi / penonaktifan aturan biasanya dilakukan melalui arahan client-connect / client-disconnect dalam file konfigurasi server, yang memanggil skrip yang sesuai ketika pengguna terhubung / terputus.


  • Otentikasi PAM Tingkat Lanjut


    Otentikasi PAM yang diperluas berarti mengubah logika login pengguna dan verifikasi kata sandi. Ini dicapai dengan menginstal plug-in yang sesuai untuk OpenVPN, yang menyediakan pembacaan dan verifikasi data dalam sumber eksternal, atau dengan menghubungkan pustaka ke sistem yang memungkinkan logika apa pun dituliskan. Salah satu pustaka tersebut adalah pam_python , yang membantu untuk skrip setiap logika verifikasi login / kata sandi melalui skrip Python.
    Jika digunakan, string verifikasi pengguna berubah sebagai berikut.


     plugin openvpn-plugin-auth-pam.so pam_python login USERNAME password PASSWORD domain mydomain.com 

    Karena “under the hood” PAM adalah algoritma dialog sistem dengan pengguna atau pustaka eksternal, dialog ini dapat dikontrol. Misalnya, hubungkan token OTP ke sistem . Pustaka LinOTP diambil hanya sebagai contoh, karena Saya kehilangan perpustakaan yang saya tulis sendiri selama pengujian di suatu tempat ¯ \ (ツ) / ¯
    Juga, contoh mudah di-google-kan dengan kata "pam_python".
    Masalah utama ketika bekerja dengan modul PAM eksternal adalah ketidakmampuan untuk mendapatkan lingkungan sesi OpenVPN di dalam yang disebut Python atau skrip lain yang dipanggil melalui pam sistem. Yaitu skrip hanya menyediakan fungsi-fungsi tersebut untuk memeriksa login / kata sandi yang ditugaskan padanya.


  • Otentikasi ditangguhkan


    Server OpenVPN mendukung apa yang disebut otentikasi "tertunda". Otentikasi "Tertunda" digunakan dalam kasus-kasus ketika layanan otentikasi tidak dapat melayani permintaan verifikasi login / kata sandi secara real time.


  • Plugin OpenVPN


    Ini adalah alam semesta paralel yang terpisah, yang mungkin diketahui, tetapi karena kebingungan, mereka tidak dapat atau takut untuk menggunakannya. Memang, menulis sebuah plug-in fungsional untuk OpenVPN membutuhkan pemrograman dalam C dengan semua yang disiratkannya. Contoh plugin sederhana disertakan dalam pohon sumber OpenVPN, atau misalnya, ada plugin untuk menunjukkan panggilan metode dari OpenVPN .



Mari kita coba mencari tahu cara kerja plugin dari OpenVPN.
Fungsi dan parameter yang digunakan untuk bekerja dengan plugin dijelaskan dalam file terpisah
Tugas utama plugin, ketika diinisialisasi oleh server OpenVPN, adalah untuk mentransfer daftar fungsi yang didukung oleh plugin dan, ketika memanggil salah satu fungsi, kembalikan kode respons yang benar, yang akan dipahami oleh server.


 #define OPENVPN_PLUGIN_FUNC_SUCCESS 0 #define OPENVPN_PLUGIN_FUNC_ERROR 1 #define OPENVPN_PLUGIN_FUNC_DEFERRED 2 

Mari kita membahas lebih rinci tentang masing-masing kelompok. Kami akan mempertimbangkan logika kerja berdasarkan otentikasi kata sandi pengguna.
Ketika server mulai, setelah membaca file konfigurasi, server memanggil fungsi OPENVPN_PLUGIN_UP dan OPENVPN_PLUGIN_ROUTE_UP. Dalam lingkungan variabel dari fungsi yang dipanggil, parameter utama dari server yang berjalan ditransfer.


 OPENVPN_PLUGIN_UP { "route_netmask_1":"255.255.0.0", "daemon_start_time":"1545994898", "ifconfig_remote":"10.150.0.2", "local_1":"172.16.100.139", "script_context":"init", "config":"/usr/local/etc/openvpn/server150.conf", "link_mtu":"1622", "ifconfig_local":"10.150.0.1", "tun_mtu":"1500", "verb":"2", "daemon_pid":"626", "route_vpn_gateway":"10.150.0.2", "proto_1":"udp", "daemon_log_redirect":"1", "daemon":"1", "route_net_gateway":"172.16.100.1", "dev_type":"tun", "route_gateway_1":"10.150.0.2", "remote_port_1":"1200", "dev":"tun150", "pluginid":"0", "local_port_1":"1200", "route_network_1":"10.150.0.0" } 

 OPENVPN_PLUGIN_ROUTE_UP { "route_netmask_1":"255.255.0.0", "daemon_start_time":"1545994898", "redirect_gateway":"0", "ifconfig_remote":"10.150.0.2", "local_1":"172.16.100.139", "script_context":"init", "config":"/usr/local/etc/openvpn/server150.conf", "link_mtu":"1622", "ifconfig_local":"10.150.0.1", "tun_mtu":"1500", "verb":"2", "daemon_pid":"626", "route_vpn_gateway":"10.150.0.2", "proto_1":"udp", "daemon_log_redirect":"1", "daemon":"1", "route_net_gateway":"172.16.100.1", "dev_type":"tun", "route_gateway_1":"10.150.0.2", "remote_port_1":"1200", "dev":"tun150", "pluginid":"2", "local_port_1":"1200", "route_network_1":"10.150.0.0" } 

Fungsi-fungsi ini dapat digunakan untuk peringatan saat startup server atau perubahan konfigurasi.
Saat menghubungkan klien, OpenVPN meminta kemampuan untuk mengaktifkan filter paket internal.


 OPENVPN_PLUGIN_ENABLE_PF { "route_netmask_1":"255.255.0.0", "daemon_start_time":"1545994898", "redirect_gateway":"0", "ifconfig_remote":"10.150.0.2", "local_1":"172.16.100.139", "script_context":"init", "config":"/usr/local/etc/openvpn/server150.conf", "link_mtu":"1622", "pf_file":"/tmp/openvpn_pf_b7a18ca8fac838679ca87ada6b8a356.tmp", "ifconfig_local":"10.150.0.1", "tun_mtu":"1500", "verb":"2", "daemon_pid":"626", "route_vpn_gateway":"10.150.0.2", "proto_1":"udp", "route_net_gateway":"172.16.100.1", "daemon":"1", "daemon_log_redirect":"1", "dev_type":"tun", "route_gateway_1":"10.150.0.2", "remote_port_1":"1200", "dev":"tun150", "pluginid":"11", "local_port_1":"1200", "route_network_1":"10.150.0.0" } 

Seperti yang Anda lihat dari dump, variabel pf_file muncul. File ini harus berisi aturan filter paket internal untuk sesi saat ini sedang diproses.
Selanjutnya, nama pengguna dan kata sandi pengguna diperiksa di fungsi OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY


 OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY { "route_netmask_1":"255.255.0.0", "route_gateway_1":"10.150.0.2", "IV_NCP":"2", "IV_COMP_STUB":"1", "daemon_start_time":"1545994898", "IV_LZ4":"1", "redirect_gateway":"0", "ifconfig_remote":"10.150.0.2", "untrusted_port":"1200", "IV_LZ4v2":"1", "local_1":"172.16.100.139", "script_context":"init", "untrusted_ip":"172.16.111.168", "config":"/usr/local/etc/openvpn/server150.conf", "username":"fa56bf61-90da-11e8-bf33-005056a12a82-1234568", "link_mtu":"1622", "pf_file":"/tmp/openvpn_pf_b7a18ca8fac838679ca87ada6b8a356.tmp", "ifconfig_local":"10.150.0.1", "tun_mtu":"1500", "auth_control_file":"/tmp/openvpn_acf_a3d0650a43b88ca1b5f305ce2c8f682.tmp", "daemon":"1", "IV_COMP_STUBv2":"1", "verb":"2", "IV_PLAT":"win", "daemon_pid":"626", "password":"12312312312312", "route_vpn_gateway":"10.150.0.2", "proto_1":"udp", "route_net_gateway":"172.16.100.1", "IV_PROTO":"2", "daemon_log_redirect":"1", "dev_type":"tun", "IV_VER":"2.4.3", "IV_LZO":"1", "remote_port_1":"1200", "dev":"tun150", "pluginid":"5", "local_port_1":"1200", "IV_TCPNL":"1", "route_network_1":"10.150.0.0" } 

Ini adalah satu-satunya tempat di mana kata sandi di lingkungan variabel hadir di tempat yang jelas.
Hasil dari fungsi ini adalah tiga kemungkinan jawaban.


 #define OPENVPN_PLUGIN_FUNC_SUCCESS 0 #define OPENVPN_PLUGIN_FUNC_ERROR 1 #define OPENVPN_PLUGIN_FUNC_DEFERRED 2 

Jika server menerima jawaban OPENVPN_PLUGIN_FUNC_DEFERRED, maka mekanisme otentikasi "tertunda" mulai beroperasi. Seperti yang kita lihat, variabel "auth_control_file" muncul di lingkungan variabel, isi dari variabel ini berisi nama file di mana respons dari sistem otentikasi akan diharapkan. Jawabannya adalah simbol 0 (untuk mengizinkan akses), 1 (untuk menolak akses) ditempatkan di file yang ditentukan. Parameter server "jendela-tangan" menentukan batas waktu dalam detik, di mana server akan menunggu respons. Sambil menunggu, lalu lintas dari klien lain tidak terganggu.


Karena kami bekerja dengan otentikasi kata sandi, fungsi verifikasi sertifikat OPENVPN_PLUGIN_TLS_VERIFY tidak dipanggil. Sebagai gantinya, OPENVPN_PLUGIN_TLS_FINAL dipanggil segera, mengkonfirmasikan pembentukan sesi.


 OPENVPN_PLUGIN_TLS_FINAL { "route_netmask_1":"255.255.0.0", "route_gateway_1":"10.150.0.2", "IV_NCP":"2", "IV_COMP_STUB":"1", "daemon_start_time":"1545994898", "IV_LZ4":"1", "redirect_gateway":"0", "ifconfig_remote":"10.150.0.2", "untrusted_port":"1200", "IV_LZ4v2":"1", "local_1":"172.16.100.139", "script_context":"init", "untrusted_ip":"172.16.111.168", "config":"/usr/local/etc/openvpn/server150.conf", "username":"fa56bf61-90da-11e8-bf33-005056a12a82-1234568", "link_mtu":"1622", "pf_file":"/tmp/openvpn_pf_b7a18ca8fac838679ca87ada6b8a356.tmp", "ifconfig_local":"10.150.0.1", "tun_mtu":"1500", "auth_control_file":"/tmp/openvpn_acf_a3d0650a43b88ca1b5f305ce2c8f682.tmp", "daemon":"1", "IV_COMP_STUBv2":"1", "verb":"2", "IV_PLAT":"win", "daemon_pid":"626", "route_vpn_gateway":"10.150.0.2", "proto_1":"udp", "route_net_gateway":"172.16.100.1", "IV_PROTO":"2", "daemon_log_redirect":"1", "dev_type":"tun", "IV_VER":"2.4.3", "IV_LZO":"1", "remote_port_1":"1200", "dev":"tun150", "pluginid":"10", "local_port_1":"1200", "IV_TCPNL":"1", "route_network_1":"10.150.0.0" } 

Selanjutnya, panggilan OPENVPN_PLUGIN_IPCHANGE disebut, yang dipanggil sebelum mengubah alamat ip klien.


 OPENVPN_PLUGIN_IPCHANGE { "route_netmask_1":"255.255.0.0", "route_gateway_1":"10.150.0.2", "trusted_ip":"172.16.111.168", "link_mtu":"1622", "IV_COMP_STUB":"1", "daemon_start_time":"1547319280", "IV_LZ4":"1", "redirect_gateway":"0", "common_name":"fa56bf61-90da-11e8-bf33-005056a12a82-1234568", "ifconfig_remote":"10.150.0.2", "IV_NCP":"2", "untrusted_port":"1200", "IV_LZ4v2":"1", "local_1":"172.16.100.139", "script_context":"init", "untrusted_ip":"172.16.111.168", "config":"/usr/local/etc/openvpn/server150.conf", "username":"fa56bf61-90da-11e8-bf33-005056a12a82-1234568", "trusted_port":"1200", "pf_file":"/tmp/openvpn_pf_4fcad505693b33f97c4fe105df8681cb.tmp", "ifconfig_local":"10.150.0.1", "tun_mtu":"1500", "auth_control_file":"/tmp/openvpn_acf_321bb12075dc0e1b5440d227220bac5d.tmp", "daemon":"1", "IV_COMP_STUBv2":"1", "verb":"3", "IV_PLAT":"win", "daemon_pid":"52435", "route_vpn_gateway":"10.150.0.2", "proto_1":"udp", "route_net_gateway":"172.16.100.1", "IV_PROTO":"2", "daemon_log_redirect":"1", "dev_type":"tun", "IV_VER":"2.4.3", "IV_LZO":"1", "remote_port_1":"1200", "dev":"tun150", "pluginid":"3", "local_port_1":"1200", "IV_TCPNL":"1", "route_network_1":"10.150.0.0" } 

Fungsi OPENVPN_PLUGIN_CLIENT_CONNECT_V2 dipanggil ketika alamat IP diatur oleh server DHCP internal.


 OPENVPN_PLUGIN_CLIENT_CONNECT_V2 { "route_netmask_1":"255.255.0.0", "route_gateway_1":"10.150.0.2", "trusted_ip":"172.16.111.168", "link_mtu":"1622", "IV_COMP_STUB":"1", "daemon_start_time":"1547319280", "IV_LZ4":"1", "dev":"tun150", "common_name":"fa56bf61-90da-11e8-bf33-005056a12a82-1234568", "time_ascii":"Sat Jan 12 18:54:48 2019", "ifconfig_remote":"10.150.0.2", "IV_NCP":"2", "untrusted_port":"1200", "IV_LZ4v2":"1", "local_1":"172.16.100.139", "script_context":"init", "untrusted_ip":"172.16.111.168", "config":"/usr/local/etc/openvpn/server150.conf", "username":"fa56bf61-90da-11e8-bf33-005056a12a82-1234568", "trusted_port":"1200", "pf_file":"/tmp/openvpn_pf_4fcad505693b33f97c4fe105df8681cb.tmp", "ifconfig_local":"10.150.0.1", "tun_mtu":"1500", "auth_control_file":"/tmp/openvpn_acf_321bb12075dc0e1b5440d227220bac5d.tmp", "daemon":"1", "IV_COMP_STUBv2":"1", "verb":"3", "IV_PLAT":"win", "daemon_pid":"52435", "time_unix":"1547319288", "redirect_gateway":"0", "route_vpn_gateway":"10.150.0.2", "proto_1":"udp", "route_net_gateway":"172.16.100.1", "IV_PROTO":"2", "daemon_log_redirect":"1", "dev_type":"tun", "IV_VER":"2.4.3", "IV_LZO":"1", "remote_port_1":"1200", "ifconfig_pool_local_ip":"10.150.0.5", "pluginid":"9", "ifconfig_pool_remote_ip":"10.150.0.6", "local_port_1":"1200", "IV_TCPNL":"1", "route_network_1":"10.150.0.0" } 

Dalam lingkungan variabel, variabel muncul yang berisi parameter terowongan "ifconfig_pool_local_ip" dan "ifconfig_pool_remote_ip".


Fungsi OPENVPN_PLUGIN_LEARN_ADDRESS dipanggil ketika server OpenVPN mempelajari koneksi alamat IP dan merutekannya. Setelah keluar dari fungsi ini, prosedur untuk menerapkan pengaturan filter paket dari file diaktifkan. Variabel lingkungan OPENVPN_PLUGIN_LEARN_ADDRESS dalam kasus ini sesuai dengan fase OPENVPN_PLUGIN_CLIENT_CONNECT_V2.


 fa56bf61-.../172.16.111.168:1200 ----- pf_check_reload : struct pf_context ----- fa56bf61-.../172.16.111.168:1200 enabled=1 fa56bf61-.../172.16.111.168:1200 filename='/tmp/openvpn_pf_343330698e4acdea34c8a8c7fb87d861.tmp' fa56bf61-.../172.16.111.168:1200 file_last_mod=1547319124 fa56bf61-.../172.16.111.168:1200 n_check_reload=1 fa56bf61-.../172.16.111.168:1200 reload=[1,15,1547319125] fa56bf61-.../172.16.111.168:1200 ----- struct pf_set ----- fa56bf61-.../172.16.111.168:1200 kill=0 fa56bf61-.../172.16.111.168:1200 ----- struct pf_subnet_set ----- fa56bf61-.../172.16.111.168:1200 default_allow=ACCEPT fa56bf61-.../172.16.111.168:1200 ----- struct pf_cn_set ----- fa56bf61-.../172.16.111.168:1200 default_allow=DROP fa56bf61-.../172.16.111.168:1200 12345678-90da-11e8-bf33-005056a12a82-1234567 ACCEPT fa56bf61-.../172.16.111.168:1200 fa56bf61-90da-11e8-bf33-005056a12a82-1234567 ACCEPT fa56bf61-.../172.16.111.168:1200 ---------- fa56bf61-.../172.16.111.168:1200 fa56bf61-90da-11e8-bf33-005056a12a82-1234567 ACCEPT fa56bf61-.../172.16.111.168:1200 12345678-90da-11e8-bf33-005056a12a82-1234567 ACCEPT fa56bf61-.../172.16.111.168:1200 -------------------- 

Ketika klien terputus, fungsi OPENVPN_PLUGIN_CLIENT_DISCONNECT dipanggil.


 OPENVPN_PLUGIN_CLIENT_DISCONNECT { "route_netmask_1":"255.255.0.0", "route_gateway_1":"10.150.0.2", "trusted_ip":"172.16.111.168", "link_mtu":"1622", "IV_COMP_STUB":"1", "daemon_start_time":"1547319280", "IV_LZ4":"1", "dev":"tun150", "common_name":"fa56bf61-90da-11e8-bf33-005056a12a82-1234568", "time_ascii":"Sat Jan 12 18:54:48 2019", "bytes_received":"30893", "IV_NCP":"2", "untrusted_port":"1200", "ifconfig_remote":"10.150.0.2", "IV_LZ4v2":"1", "local_1":"172.16.100.139", "script_context":"init", "untrusted_ip":"172.16.111.168", "config":"/usr/local/etc/openvpn/server150.conf", "username":"fa56bf61-90da-11e8-bf33-005056a12a82-1234568", "trusted_port":"1200", "pf_file":"/tmp/openvpn_pf_4fcad505693b33f97c4fe105df8681cb.tmp", "ifconfig_local":"10.150.0.1", "tun_mtu":"1500", "auth_control_file":"/tmp/openvpn_acf_4bdddbada2885cde42cd3cb1b85d77e5.tmp", "daemon":"1", "IV_COMP_STUBv2":"1", "verb":"3", "IV_PLAT":"win", "daemon_pid":"52435", "time_unix":"1547319288", "redirect_gateway":"0", "route_vpn_gateway":"10.150.0.2", "proto_1":"udp", "route_net_gateway":"172.16.100.1", "IV_PROTO":"2", "daemon_log_redirect":"1", "time_duration":"3781", "dev_type":"tun", "IV_VER":"2.4.3", "IV_LZO":"1", "bytes_sent":"22684", "remote_port_1":"1200", "ifconfig_pool_local_ip":"10.150.0.5", "pluginid":"7", "ifconfig_pool_remote_ip":"10.150.0.6", "local_port_1":"1200", "IV_TCPNL":"1", "route_network_1":"10.150.0.0" } 

Dalam lingkungan variabel, durasi koneksi dan lalu lintas pengguna ditambahkan.


Seperti yang Anda lihat, karena banyaknya data dalam panggilan yang berbeda, menulis dan men-debug plug-in dalam bahasa pemrograman C (C ++) akan menjadi tugas yang agak memakan waktu.
Untuk memperluas fungsionalitas, diputuskan untuk membuat "keajaiban" pertama untuk proyek internal, dan kemudian memasukkannya ke dalam domain publik :)
Setelah membaca panjang kode sumber OpenVPN dan berbagai contoh plugin yang sangat khusus, sebuah proyek ditulis yang menggunakan Python sebagai bahasa pemrograman untuk logika pemrosesan sesi. Kode adalah plug-in dalam bahasa C yang terhubung ke OpenVPN, yang mengirim semua permintaan ke plug-in, mengirimkan modul ke Python melalui referensi c-api .


Proxy plugin python OpenVPN


Mengapa modul Python?


Referensi python c-api yang bekerja dengan file python secara langsung tidak bekerja dengan benar dengan memuat pustaka python.


Bagaimana cara kerjanya?


Ketika plugin diinisialisasi dalam OpenVPN, plugin mengembalikan daftar yang disembunyikan dari semua fungsi yang dapat dilayaninya. Ketika fase koneksi berikutnya atau acara internal terjadi, OpenVPN memanggil fungsi yang sesuai dari plugin. Plugin mengubah variabel lingkungan dan parameter yang diteruskan ke fungsi menjadi struktur, menginisialisasi python dan meneruskan struktur ke prosedur yang sesuai dari modul python. Prosedur mengembalikan salah satu dari tiga jawaban untuk plugin (0 - Sukses, 1 - Kesalahan, 2 - Ditangguhkan). Responsnya diubah dan dikembalikan oleh OpenVPN.


Harap dicatat bahwa semua panggilan modul "stateless", yang berarti bahwa prosedur tidak ingat dan tidak tahu apa yang terjadi sebelumnya pada panggilan lain. Anda hanya dapat fokus pada lingkungan variabel yang dilewatkan ke plugin dari OpenVPN.


Di dalam modul python, Anda dapat menerapkan logika apa pun dengan menghubungkan pustaka dan sumber daya yang diperlukan. Jika Anda tidak yakin tentang kecepatan pemeriksaan, maka gunakan konfirmasi "menunggu keputusan".


Menggunakan pengelompokan pengguna yang terhubung ke layanan, melalui pf_file Anda dapat mengatur interaksi jaringan antara pengguna dan sumber daya lainnya dengan cukup baik. Pada gilirannya, dengan menghubungkan plug-in untuk pemantauan, akan selalu memungkinkan untuk mengelola sesi klien melalui antarmuka manajemen OpenVPN.


Selama pengujian proyek, mekanisme pembuatan kata sandi dikembangkan, mirip dengan token jwt, tetapi dengan ukuran yang lebih kecil.


Intinya sederhana. Token berisi pengidentifikasi klien dan tanggal kedaluwarsa. Untuk menandatangani token, HMAC_SHA1 dengan kunci pribadi digunakan. Setelah token ditandatangani, konten teks rusak oleh tanda tangan dan dikonversi ke base64. Dengan demikian, "penyegelan" token diperoleh. Token yang disegel digunakan sebagai kata sandi pengguna. Jika terjadi perubahan yang tidak sah pada blok data, xor rusak, jika xor rusak, maka verifikasi tandatangan rusak. Tanpa kunci pribadi, tanda tangan tidak dapat diubah.


Jika Anda tidak ingin mengontrol waktu validitas kata sandi dengan tangan Anda, maka hasilkan token semacam itu, dan periksa validitasnya di dalam plugin tanpa memanggil layanan eksternal. Skema ini sangat nyaman untuk pembuatan kata sandi sesi untuk waktu tertentu. Pada saat yang sama, Anda dapat mentransfer konten token ke sistem kontrol eksternal dan itu akan mengkonfigurasikan dirinya untuk memutuskan sambungan pengguna setelah token berakhir.


Saya harap informasi dalam artikel ini bermanfaat bagi Anda.
Terima kasih telah meluangkan waktu untuk membacanya.
Jika Anda memiliki pertanyaan, saya akan mencoba menjawab apa yang saya bisa.


© Aborche 2019
Aborche

Source: https://habr.com/ru/post/id435802/


All Articles