psql -Upgsql template1 ctreate database vpn; \q
psql -Upgsql vpn; create table users ( "id" serial, "login" varchar(32) not null, "name" varchar(32) not null, "password" varchar(32) not null "groups_id" integer not null, "active" boolean not null default true, "hwkey" boolean not null default true, ); create table groups ( "id" serial, "groupname" varchar(32) not null, "active" boolean not null default true ); create table log ( "id" serial, "date" timestamp, "users_id" integer not null, "realaddress" varchar(32), "virtualaddress" varchar(32), "status" varchar(32) ); create table stat ( "id" serial, "date" timestamp, "login" varchar(32); "realaddress" varchar(32), "virtualaddress" varchar(32) );
psql -Upgsql template1 create user ovpn WITH PASSWORD 'password'; \q psql -Upgsql vpn grant select on users TO ovpn; grant select on groups to ovpn; grant all on log to ovpn; grant all on stat to ovpn; \q
psql -Upgsql vpn insert into groups values(dafault,'admins',true); insert into groups values(default,'rdp',true); insert into users values(default,100101,' ..',md5('password'),(select id from groups where groupname = 'admins'),true,false); insert into users values(default,100102,' ..',md5('password'),(select id from groups where groupname = 'rdp'),true,false);
cd /root/ca openssl req -x509 -newkey rsa:1024 -keyout /root/ca/ssl.key/ca.key -out /root/ca/ssl.crt/ca.crt -days 9999 -nodes -subj "/C=RU/ST=MSK/L=MSK/O=COMPANY/CN=CA"
openssl req -new -newkey rsa:1024 -nodes -keyout /root/ca/ssl.key/ovpn.key -subj /CN=ovpn.domain.ru -out /root/ca/ssl.csr/ovpn.csr openssl ca -config ca.conf -in /root/ssl.csr/ovpn.csr -out /root/ssl.crt/ovpn.crt -batch
#!/usr/bin/perl use Getopt::Long; GetOptions ('a=s' => \$action, 'u=s' => \$user, 'O=s' => \$ou, 'o=s'=> \$options, 'help' => sub {HelpMessage()}); # variables $ca='ca'; $ca_dir='/root/ca/'; $key_id='1000'; if (length($action)==0){ HelpMessage(); exit; } if ($action=~/^help$/){ print "actions: adduser # Add a new User certificate gen_revoke # Generate revoke file\n"; exit; } if ($action=~/^adduser$/){ adduser(); } if ($action=~/^gen_revoke$/){ gen_revoke(); } sub HelpMessage { print "usage: ".$0. " -a <adduser|gen_revoke> -u <login> -O <VPN>\n"; exit; } sub adduser { $p12_password = randomPassword(6); print "~~Add User(Soft)~~\n"; if (length($user)==0 || length($ou)==0){ print "Error, User and OU must be\n"; exit; } # create cert print "create User certificate\n"; system(`openssl req -new -newkey rsa:1024 -nodes -keyout $ca_dir/ssl.key/$user.key -subj /CN=$user/OU=$ou -out $ca_dir/ssl.csr/$user.csr`); # sign USER cert print "sign certificate\n"; system(`openssl ca -config ca.conf -in $ca_dir/ssl.csr/$user.csr -out $ca_dir/ssl.crt/$user.crt -batch`); # p12 print "create p12\n"; system(`openssl pkcs12 -export -in $ca_dir/ssl.crt/$user.crt -inkey $ca_dir/ssl.key/$user.key -certfile $ca_dir/ssl.crt/$ca.crt -out p12/$user.p12 -passout pass:$p12_password`); print "p12_password: ".$p12_password."\n"; # unlink files unlink('$ca_dir/ssl.csr/$user.csr','$ca_dir/ssl.crt/$user.crt','$ca_dir/ssl.key/$user.key'); } sub gen_revoke { # gen CRL system(`openssl ca -config $ca_dir/ca.conf -gencrl -crldays 365 -out $ca_dir/ssl.crl/certPEM.crl`); system(`openssl crl -in $ca_dir/ssl.crl/certPEM.crl -outform DER -out $ca_dir/ssl.crl/certDER.crl`); print "pls copy ./ssl.crl/certDER.crl to OpenVPN server\n"; } sub randomPassword { $password; $_rand; $password_length = $_[0]; if (!$password_length) { $password_length = 10; } @chars = split(" ", "ABCDEFGHIJK LMNOPQRSTUVWXYZ abcdefghijklmnopqrstu vwxyz 0 1 2 3 4 5 6 7 8 9"); srand; for (my $i=0; $i <= $password_length ;$i++) { $_rand = int(rand 41); $password .= $chars[$_rand]; } return $password; }
/root/ca/gen_cert.pl -a adduser -U 100101 -O VPN /root/ca/gen_cert.pl -a adduser -U 100102 -O VPN
/root/ca/gen_cert.pl -a gen_revoke
port 1194 proto udp dev tun ca /usr/local/etc/ssl/ca.crt cert /usr/local/etc/ssl/ovpn.crt key /usr/local/etc/ssl/ovpn.key crl-verify /usr/local/etc/ssl/certPEM.crl dh /usr/local/etc/ssl/dh2048.pem tls-verify "/usr/local/etc/openvpn/scripts/intra.pl tls-verefy" topology subnet server 172.16.40.0 255.255.255.0 push "route 172.16.0.0 255.255.0.0" push "dhcp-option DOMAIN domain.local" push "dhcp-option DNS 172.16.38.10" client-connect /usr/local/etc/openvpn/scripts/intra.pl client-disconnect /usr/local/etc/openvpn/scripts/intra.pl auth-user-pass-verify "/usr/local/etc/openvpn/scripts/intra.pl auth-user-pass-verify" via-env keepalive 10 120 persist-key persist-tun status /var/log/openvpn-status.log log /var/log/openvpn.log log-append /var/log/openvpn.log management localhost 7505 verb 3
#!/usr/bin/perl use DBI; use Digest::MD5 qw(md5_hex); $dbh=DBI->connect("DBI:Pg:dbname=vpn;host=localhost","ovpn","password"); ($script_type,$common_name,$ifconfig_pool_remote_ip,$untrusted_ip) = ($ENV{'script_type'},$ENV{'common_name'},$ENV{'ifconfig_pool_remote_ip'},$ENV{'untrusted_ip'}); if ($script_type eq "client-connect") { insert_to_firewall_group(); logging('start'); } if ($script_type eq "client-disconnect") { delete_from_firewall_group(); logging('stop'); } if ($script_type eq "tls-verefy"){ tls_verefy(); } if ($script_type eq "auth-user-pass-verify"){ auth_user_pass_verefy(); } sub get_group { my $req="SELECT groups.id FROM groups INNER JOIN users ON (users.groups_id = groups.id) WHERE users.login='$common_name'"; @row = $dbh->selectrow_array($req); } sub insert_to_firewall_group { get_group(); `/sbin/ipfw table 0 add $untrusted_ip`; `/sbin/ipfw table $row[0] add $ifconfig_pool_remote_ip`; } sub delete_from_firewall_group { get_group(); `/sbin/ipfw table 0 delete $untrusted_ip`; `/sbin/ipfw table $row[0] delete $ifconfig_pool_remote_ip`; } sub tls_verefy { ($script_type, $depth, $x509) = @ARGV; @X509=split(",",$x509); $X509[0] =~s/^OU=//g;$ou = $X509[0]; $X509[1] =~s/^ CN=//g; $cn = $X509[1]; @ous=('VPN'); if ($depth == 0) { #verefy OU foreach(@ous){ if ($_ eq $ou) { $ou_status = 1; #exit 0; } } #verefy CN $req = "SELECT login FROM users WHERE login = '$cn' AND active = true"; @row = $dbh->selectrow_array($req); if ($row[0] eq $cn) { $cn_status = 1; } if ($ou_status == 1 && $cn_status == 1){ exit 0; } exit 1; } } sub logging { ($status) = @_; $date = `date '+%Y-%m-%d %H:%M:%S'`; chop $date; $req = "INSERT INTO log VALUES(DEFAULT,'$date',(SELECT id FROM Users WHERE login='$common_name'),'$untrusted_ip','$ifconfig_pool_remote_ip','$status')"; $dbh->do($req); if ($status eq "start"){ $st = "INSERT INTO stat VALUES(DEFAULT,'$date','$common_name','$untrusted_ip','$ifconfig_pool_remote_ip')"; $dbh->do($st); } else { $st = "DELETE FROM stat WHERE login='$common_name'"; $dbh->do($st); } } sub auth_user_pass_verefy { $username = $ENV{'username'}; $password = $ENV{'password'}; $common_name = $ENV{'common_name'}; $q_hw = "SELECT hwkey FROM users WHERE login = '$common_name' AND active = true"; @row = $dbh->selectrow_array($q_hw); if ($row[0] == 1 ){ exit 0; } $password = md5_hex($password); $req = "SELECT login FROM users WHERE login = '$username' AND password = '$password' AND active = true"; @row = $dbh->selectrow_array($req); if ($row[0] eq $username) { exit 0; } exit 1; }
#!/bin/sh ipfw='/sbin/ipfw -q' clients_real_ip="table(0)" # , admins="table(1)" # admins rdp="table(2)" # rdp ${ipfw} flush # -- -- ${ipfw} add allow ip from ${admins} to any # ${ipfw} add allow tcp from ${rdp} to any 3389 # rdp RDP ${ipfw} add deny all from ${rdp} to any # rdp # -- --
client dev tun proto udp remote ovpn.domain.ru 1194 resolv-retry infinite nobind persist-key persist-tun script-security 3 ca "C:\\Program Files\\OpenVPN\\config\\ca.crt" cryptoapicert "SUBJ:100101" auth-user-pass comp-lzo log "C:\\Program Files\\OpenVPN\\log\\client.log" log-append "C:\\Program Files\\OpenVPN\\log\\client.log" verb 3 route-delay 5 30 tap-sleep 5
require 'pg' require 'geoip' $conn = PG.connect( :hostaddr=>'ovpn.domain.local', :user=>'ovpn',:password=>'password',:dbname=>'vpn') def getVPNstat all = Hash.new({ value: 0 }) result = $conn.exec( "SELECT COALESCE(users.name,stat.login) AS name,stat.realaddress AS ip FROM stat,users WHERE stat.login = users.login") result.each do | row | user = row['name'] user = user[0..8].downcase ip = row['ip'] country = geoip(ip) all[user] = {label: user,value: country } end send_event('vpnstat', { items: all.values }) end def geoip(ip) c = GeoIP.new('/usr/local/www/ruby/dashboard/geoip/GeoIP.dat').country(ip) country = c[4] return country end SCHEDULER.every '20s' do getVPNstat end
wget -N http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
<li data-row="1" data-col="5" data-sizex="1" data-sizey="2"> <div data-id="vpnstat" data-view="Currency" data-unordered="true" data-title="VPN" style="background-color:green"></div> </li>
Source: https://habr.com/ru/post/324164/
All Articles