LinOTP是Google官方开源的one time password企业管理应用,但在国内使用的企业貌似不多。实习的时候老师要求配置一个系统,但国内很少有人给出了实际使用方法,而且官方的document写得真的是不忍吐槽。于是就自己写一个简单教程,也算是对官方教程的一个简单翻译和整合。
看完这个教程,你将能搭建最基础的应用。但是如果你想把它作为你的企业应用,最好还是自己摸索一番,或者直接联系开发者和邮件列表。
ubuntu和debian有标准的一键安装,加入软件源后直接可用,red hat和centos等其他发行版需要使用pypi安装,并且手动安装所有依赖。 这里以centos6.5为例子,说明简要的安装过程:
首先安装virtualenv用于建立一个隔离的python环境,由于virtualenv的存在,我们可以在任何一个发行版中用pypi安装和使用linotp
yum install python-virtualenv
单独建立一个文件夹来构造linotp独立的python环境
mkdir -p /opt/LINOTP
virtualenv –-no-site-packages /opt/LINOTP
进入LINOTP文件夹,开始并切换工作目录到当前虚拟环境,每次需要启动或者使用LINOTP文件夹内的app时都需要使用下面命令
cd /opt/LINOTP
source bin/activate
使用下面命令退出虚拟环境
deactivate
我们需要在虚拟环境中安装所需的依赖
yum install python-devel swig gcc openssl-devel openldap-devel mysql-devel
现在可以直接使用pip安装linotp
pip install linotp
安装使用各种token所需要的依赖(可能并不是所有包到都能安装)
pip install pil
pip install m2crypto
pip install psycopg2
pip install MySQL-python
pip install SMSProvider
注意:为了方便,我们应该把配置文件都放在/etc文件夹下,而不是直接放在/opt/LINTOP/etc/linotp2下面,所以直接拷贝配置文件到/etc目录下
cp -rf /opt/LINOTP/etc/linotp2 /etc/linotp2
警告:pip不会自动的更新所安装的软件,所以我们安装的依赖并不是最新的,也最好不要手动编译安装,LinOTP提供了更新命令
linotp-pip-update
,但是一定不要使用(至少在centos6.5下不要使用),因为高版本的库并不支持linotp。
如果使用的是mysql,可以直接使用下面命令
mysql -u root -p mysql
create database L2demo;
grant all privileges on L2demo.* to 'linotp'@'localhost' identified by 'mySecret';
flush privileges;
quit;
注意:linotp里面有个默认配置叫
/etc/linotp2/linotp.ini.example
,为使用此配置,我们需要重命名该文件为/etc/linotp2/linotp.ini
在linotp.ini中找到sqlalchemy.url
,并修改为
sqlalchemy.url = mysql://linotp:mySecret@localhost/L2demo
还需要创建一个加密密钥
dd if=/dev/urandom of=/etc/linotp2/encKey bs=1 count=96
创建log文件夹
mkdir /var/log/linotp
现在就可以正式创建数据库表单了
paster setup-app /etc/linotp2/linotp.ini
我们需要借用apache使用webUI的管理页面,首先使用下面命令创建一个文件
htdigest /etc/linotp2/admins “LinOTP2 admin area” admin
我们需要安装并激活以下模块
yum install mod_wsgi
yum install mod_ssl
注意:在使用过程中端口会遭到iptables的拦截,这时候我们可以简单的关闭iptables
/etc/init.d/iptables stop
或者开放指定端口,在/etc/sysconfig/iptables文件中添加如下命令(或许还需要更多端口)
-A INPUT -p tcp -m tcp --sport 443 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m tcp --sport 3389 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 3389 -j ACCEPT
-A INPUT -p tcp -m tcp --sport 5001 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 5001 -j ACCEPT
还需要建立一个wsgi的文件夹,不然WSGI模块不能正常启动
mkdir /var/run/wsgi
现在我们可以进一步配置apache-server了。
首先创建一个认证文件touch /etc/[httpd|apache2]/linotp-auth.conf
(centos是httpd文件夹下)
在此文件中添加以下内容
AuthType Digest
AuthName “LinOTP2 admin area”
AuthDigestProvider file
AuthUserFile /etc/linotp2/admins
Require valid-user
无论LinOTP的配置文件放在哪里,都需要包含以下内容。这里我直接添加到/etc/httpd/conf/httpd.conf
文件的最后(针对不同的系统,可能要对文件中文件的路径进行修改)
Listen 443
WSGIPythonHome /opt/LINOTP
WSGISocketPrefix /var/run/wsgi
<VirtualHost _default_:443>
ServerAdmin webmaster@localhost
DocumentRoot /var/www
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
Alias /doc/html /usr/share/doc/linotpdoc/html
WSGIScriptAlias / /etc/linotp2/linotpapp.wsgi
#
# The daemon is running as user 'linotp'
# This user should have access to the encKey database encryption file
WSGIDaemonProcess linotp processes=1 threads=15 display-name=%{GROUP} user=linotp
WSGIProcessGroup linotp
WSGIPassAuthorization On
<Location /admin>
Include /etc/httpd/linotp-auth.conf
</Location>
<Location /audit>
Include /etc/httpd/linotp-auth.conf
</Location>
<Location /gettoken>
AuthType Digest
AuthName "LinOTP2 gettoken"
AuthDigestProvider file
AuthUserFile /etc/linotp2/gettoken-api
Require valid-user
</Location>
<Location /manage>
Include /etc/httpd/linotp-auth.conf
</Location>
<Location /selfservice>
# The authentication for selfservice is done from within the application
</Location>
<Location /system>
Include /etc/httpd/linotp-auth.conf
</Location>
<Location /license>
Include /etc/httpd/linotp-auth.conf
</Location>
<Location /validate>
# No Authentication
</Location>
ErrorLog /var/log/httpd/error.log
LogLevel warn
# Do not use %q! This will reveal all parameters, including setting PINs and Keys!
# Using SSL_CLIENT_S_DN_CN will show you, which administrator did what task
LogFormat "%h %l %u %t %>s \"%m %U %H\" %b \"%{Referer}i\" \"%{User-agent}i\" " LinOTP2
CustomLog /var/log/httpd/ssl_access.log LinOTP2
# SSL Engine Switch:
# Enable/Disable SSL for this virtual host.
SSLEngine on
# If both key and certificate are stored in the same file, only the
# SSLCertificateFile directive is needed.
SSLCertificateFile /etc/ssl/certs/linotpserver.pem
SSLCertificateKeyFile /etc/ssl/private/linotpserver.key
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
BrowserMatch ".*MSIE.*" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
ErrorDocument 500 "<h1>Internal Server Error</h1> Possible reasons can be missing modules or bad access rights \
on LinOTP configuration files or log files. Please check the apache logfile \
<pre>/var/log/httpd/error_log</pre> for more details."
</VirtualHost>
注意:centos的mod_ssl在
/etc/httpd/conf.d/
中自带了一个ssl.conf
的配置文件,里面已经定义了VirtualHost
,所以这里需要相应的调整不然端口会发生冲突。(为方便可以直接重命名为ssl.conf.old
)
注意:如果发现
linotpserver.pem
等密钥不存在,那我么需要手动生成一些
WSGI的进程默认使用名字叫linotp
的用户,所以我们需要新建一个用户来使用它
adduser -r linotp -d /opt/LINOTP
现在可以把/opt/LINOTP/etc/linotp2/linotpapp.wsgi
文件复制到/etc/linotp2
文件夹中
cp /opt/LINOTP/etc/linotp2/linotpapp.wsgi /etc/linotp2
最后查看我们建立的文件的权限,只有在适合的权限下才能正常使用linotp-server。我们希望看到的权限如下
注意:如果权限不当,可以使用
linotp-fix-access-rights -f /etc/linotp2/linotp.ini -u linotp
来修复权限
重启apache和mysql
apachectl restart#输入你设定的密码
service mysqld restart
现在我们可以从命令行启动服务器了
paster serve /etc/linotp2/linotp.ini
linotp会监听你在linotp.ini中定义的端口,接下来在浏览器中访问http://<yourserverIP>:5001/manage
就可以进入manage的页面。
警告!!!:这里的管理页面是不需要用户名和密码就能登录的,只供测试使用。密码需要自行在apache中配置
使用LinOTP config->useridresover
创建一个useridresover。这里有三种创建方式
当然最间但的是flatfile方式创建,这中格式的用户文件和*nix中的/etc/passwd文件格式一样,因此我们可以直接导入文件/etc/passwd
,导入后刷新就可以看到成功导入的用户。但是这样做有一个问题,/etc/passwd
文件中的并没有保存用户密码/加密后的信息,就让我们的用户实际无法登录,因此更好更简洁的办法是把是使用
linotp-create-pwidresolver-user -u [username] -i [userid] -p [password] -d [description]>> passwd-file
创建测试用户,可以用此方法创建多个,然后导入的时候直接导入passwd-file
文件
LinOTP config->realms
按提示创建就行,并且指定一个默认的用户组
token可以从文件中导入,可以从官方文档中查看支持的token和导入方法
更简单的方法是手动创建token,点击左边侧烂enroll
可以看到创建token选项,这里我选择HMAC eventbased
,并勾选Generate HMAC key
点击enroll
看到了生成的二维码,点击OK
就可以在主页上Token view
看到生成的token
方法很简单,在Token view
单击想要的token,切换到User view
下面单击相应的user,就可以在页面的左上角看到相应的信息类似如下
这是最重要的一部分,关系到了用户的权限问题。policy有很多种类型,具体可以参见官方文档http://www.linotp.org/doc/latest/part-management/policy/index.html
这里,我以selfpolicy为例。
action是最重要的一部分,它直接指明了user的权限。不同的user类型有不同的权限,官方文档给出了一个推荐的最佳配置http://www.linotp.org/doc/latest/part-management/policy/best-practice.html
policy配置好之后,就可以从浏览器登录用户了。
浏览器输入http://[yourIP]:5001/account/login
根据用户名和密码就可以登录
从manage页面我们还可以设置LinOTP config->system config
,不过配置对简单的实验影响不大,官方文档有也把配置方式写得很清楚http://www.linotp.org/doc/latest/part-management/system-config.html
登录后我们可以看到如下界面,根据对policy->action
的设置,界面可能有所不同。
官方文档写得很简要http://www.linotp.org/doc/latest/part-user/workflow.html
这里,我通过一个小例子说明。
比如我们选择Enroll Google Authenticator
,然后点击Enroll Google Authenticator
可以看到页面左上生成了一个token(这个时候退回去看manage页面,发现也生成了一个token)。然后在你的iphone/Android上安装 google authenticator ,并扫描这个时候生成的二维码。再次使用该应用时候,就可以看到手机上出现了六位数字。这个数字就是你登录自己应用的时候所需要的密码。
我们可以登录http://[yourIP]:5001/auth/index
来测试应用是否成功。