FreeBSD下安装dante(sockd)并使用pam-pwdfile进行认证
dante-server 是一个很好的socks4/5代理服务器软件,小巧且功能强大。
操作系统为 FreeBSD 11.1 64位,未安装桌面环境。安装过程记录如下:
安装 dante-server
sudo pkg install dante
配置 dante-server
sudo vi /usr/local/etc/sockd.conf
输入:
logoutput: stderr /var/log/sockd.log internal: em0 port = 1080 external: em0 socksmethod: pam.username #如果想使用系统用户信息验证的话可以改为 username,需要匿名访问改为none;也可以是多个验证方法,中间用空格隔开。 user.privileged: root user.unprivileged: nobody client pass { from: 0.0.0.0/0 port 1-65535 to: 0.0.0.0/0 log: connect error } socks pass { from: 0.0.0.0/0 to: 0.0.0.0/0 log: connect error socksmethod: pam.username #必须是上面socksmethod参数中的一个或多个。 }
如果使用系统用户信息进行验证的话可以跳过下面的3-6步。
安装 libpam-pwdfile
sudo pkg install pam-pwdfile
配置 PAM
sudo vi /etc/pam.d/sockd
输入:
auth required pam_pwdfile.so pwdfile /usr/local/etc/sockd.passwd account required pam_permit.so
生成密码文件
sudo touch /usr/local/etc/sockd.passwd
管理用户
sudo htpasswd -d /etc/sockd.passwd 用户名 #添加或更新用户信息 sudo htpasswd -D /etc/sockd.passwd 用户名 #删除用户信息
如果系统中没有安装htpasswd,也可以用下面的perl脚本进行管理。
根据实际情况修改下面两个参数
my $htpasswdfile = /usr/local/etc/sockd.passwd; #密码文件保存的位置
my $algorithm = 1; #加密算法,1为MD5,安全性较低,如果pam-pwdfile的版本较高,可以改为5(SHA-256)或6(SHA-512)sudo vi /usr/local/bin/sdpasswd
输入:
#!/usr/bin/env perl # This file is part of danted PAM. # # This script is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. use warnings; use strict; use File::Copy; my $htpasswdfile = "/usr/local/etc/sockd.passwd"; my $algorithm = "1"; # 1 MD5; # 5 SHA-256; # 6 SHA-512; if ((getpwuid $>) ne 'root'){print ("Have to run with root users!\n");exit(-1);}; my $parameter; my $operation; my $username; my $password; $0 =~ m/(.+\/)(.*)/; chomp(my $cmd = $2); foreach $parameter (@ARGV) { if ($parameter =~ m/^-(\S+)/) { $operation = lc($1); } else { if (! defined $username) { $username = $parameter; } elsif (! defined $password){ $password = $parameter; } } } if (! defined $operation){ &usage($cmd);} if ($operation eq '-help'){ &usage($cmd);} if ($operation !~ m/^[cdvn]/) { &usage($cmd, $operation);} if (! defined $username){$username = &getinput("Enter your username:");} if ((! defined $password) && ($operation ne 'd')){ my $password1 = &getinput("New password:",""); my $password2 = &getinput("Re-type new password:",""); if ($password1 ne $password2) { print ("password verification error\n"); exit 2} $password = $password1; } my @htpasswd; my $passstrs = "User $username not found"; my $randstr = &randstr (8); my $newpassstr; if (defined $password) {$newpassstr = crypt ($password, "\$$algorithm\$$randstr\$");} if ($operation eq 'n') {print ("$username:$newpassstr\n"); exit 0;} my @username; my @htinfo; open (my $htpasswd, "< $htpasswdfile") || print ("Can't modify file \"$htpasswdfile\"\n") && exit 3; while (<$htpasswd>) { if ($_ =~ m/(\w+):(\S+)/g){push @username,$1;} push @htinfo,$_;} close $htpasswd; foreach (@htinfo) { my $sig; if ($_ =~ m/(\w+):\$(\w+)\$(\S+)\$(\S+)/g){ my $name = $1; my $type = $2; my $salt = $3; my $hash = $4; if (($operation eq 'c') && ($username eq $1)){push @htpasswd,"$username:$newpassstr\n"; $passstrs = "Updating password for user $username"; $operation = 'w'; next} if (($operation eq 'd') && ($username eq $1)){$passstrs = "Deleting password for user $username"; $operation = 'w'; next} if (($operation eq 'v') && ($username eq $1)){ my $newpassstr = crypt ($password, "\$$2\$$3\$"); if ($_ eq "$username:$newpassstr\n") {$passstrs = "Password for user $username correct.";} else {$passstrs = "password verification failed";} last } push @htpasswd, $_; } } if ($operation eq 'c') {push @htpasswd,"$username:$newpassstr\n"; $passstrs = "Adding password for user $username"; $operation = 'w';} if ($operation eq "w") { open (my $htpasswd, "> $htpasswdfile") || &showmsg ("Can't modify file \"$htpasswdfile\"\n") && exit 4; foreach (@htpasswd){ print $htpasswd "$_"; } close $htpasswd; } print "$passstrs\n"; exit 0; sub getinput { print ($_[0]); if (defined($_[1])) {system "stty -echo";} chomp(my $return = <STDIN>); if (defined($_[1])) {system "stty echo";print "\n";} return $return; } sub randstr { my @source = (0..9,'a'..'z','A'..'Z','/','.'); return join '', map { $source[int rand @source] } 0..($_[0]-1); } sub usage { if (defined($_[1])){ print ("$_[0]: illegal option -- $_[1]\n");} print ("Usage:\n"); print (" $_[0] -[c|d|v] username\n"); print (" $_[0] -[c|d|v] username password\n"); print ("\n"); print (" -n Don't update file; display results on stdout.\n"); print (" -c Create or Update the specified user.\n"); print (" -d Delete the specified user.\n"); print (" -v Verify password for the specified user.\n"); exit 1; }
使用方法:
sudo sdpasswd -n 用户名 #直接在控制台显示加密后的用户信息
sudo sdpasswd -c 用户名 #添加或更新用户信息
sudo sdpasswd -d 用户名 #删除用户信息
sudo sdpasswd -v 用户名 #核对用户密码
启动服务
service sockd start
查看是否监听成功:
lsof -i:1080
显示类似信息即为成功运行
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME danted 19485 nobody 9u IPv4 0xfffff80003d38820 0t0 TCP Hostname:socks (LISTEN)
扫描二维码推送至手机访问。
版权声明:本文由DigitalFire发布,如需转载请注明出处。