如何部署Oracle Linux 9.x PrivacyIDEA?
- By : Will
- Category : privacyIDEA

1 基础知识
1.1 privacyIDEA的介绍
1.1.1 privacyIDEA是什么?
– 模块化的身份验证服务器
– 可通过双因素身份验证来增强应用程序的安全
1.1.2 privacyIDEA的作用
– 可增强本地登录的安全性
– 可增强VPN的安全性
– 可增强远程访问的安全性
– 可增强SSH连接的安全性
– 可增强访问网站或Web门户网站的安全性
注,privacyIDEA最初有如下作用,
– 作为OTP服务器的提供OTP(一次性密码)认证设备
– 也可用户其他设备的Challenge Response、U2F、Yubikeys、SSH秘钥和x509证书
1.1.3 软件特点
– 运行于Linux系统
– 完全开源,基于AGPLv3的许可发布
– 系统由Python语言编写
– 使用Flask的Web框架
– 使用SQL数据库作为数据存储
1.1.4 支持的用户来源
– LDAP服务
– Active Directory
– SQL数据库
– 平面文件
– SCIM服务
1.2 privacyIDEA的功能
1.2.1 支持的认证设备
– Simple pass token,即简单的令牌传递(实际总回应ACCEPTED)
– HOTP/TOTP,支持的品牌有SafeNet/eToken Pass、Safeword、Feitian、Smartdisplayer(所有OATH令牌)
– Push-Button key fobs,即按钮式密码卡
– OTP cards,即One-time Password或称动态口令
– Smartphone Apps,如Google Authenticator或FreeOTP
– MOTP,即移动密码系统
– QR code,即通过扫描QR码验证TiQR令牌
– RADIUS token,即将身份验证请求转发给RADIUS服务器
– REMOTE token,即将身份验证请求转发给别的privacyIDEA服务器
– Email-Token,即通过电子邮件发送的一次性密码
– SMS-Token,即通过短信发送一次性密码(SMSOTP,mTAN,mobileTAN)
– Yubikey in all Modes,即Yubikey的所有模式,包括OATH HOTP、Challenge Response、Yubico AES
– Day OTP token,即通过一天使用一个密码并在第二天更改令牌的密码的验证设备
– Password token,即将OTP PIN与附加密码的组合,适用于内部丢失令牌的场景
– SSH public key,即SSH令牌包含公共的SSH秘钥,此SSH秘钥可分发到计算机用于SSH登录
– x509 certificates,即由证书颁发机构颁发的x509证书
– Registration Token,即注册令牌,便于部署
– python class inherited from TokenClass,即从TokenClass继承的新Python类来添加新的身份验证设备
1.2.2 支持的认证接口
– 支持REST API(符合RESTful设计架构的接口)和JWT(JSON Web Token)身份验证
– 支持返回JSON输出
– 支持与SimpleSAMLphp一起充当SAML身份提供程序
– 插件可用于,
– – FreeRADIUS
– – PAM(支持离线OTP)
– – Apache2
– – OTRS
– – Django
– – ownCloud
– – WordPress
– – TYPO3
– – Contao
– – dokuwiki等等
1.2.3 支持的登录方式
– 用户或管理员可以登录privacyIDEA WebUI
– 用户或管理员可针对其他用户(例如域密码)或针对privacyIDEA(使用OTP)进行身份验证
1.2.4 支持的管理
– 支持创建解析器和领域
– 支持查看审核日志
– 支持管理令牌,具体是注册或删除、分配或取消分配、设置PIN、导入、启用或禁用、重新同步令牌、查看令牌详情
– 支持获取特定的令牌OTP值
– 支持获取特定OTP值的令牌序列号
– 支持定义令牌默认设置
– 支持令牌有效期
– 支持令牌最大使用量(根据每天或单个令牌的使用计数,例如可限制10此成功登录或20此尝试登录,或多少周内有效)
– 支持创建丢失的令牌,即将临时令牌注册给丢失令牌的用户
– 支持定义策略
– 支持通过RADIUS侧列进行简单迁移
– 支持定义根据任何的操作定义任何操作
1.2.5 支持的自助服务
– 支持用户可通过WebUI自行管理自己的令牌
– 支持通过QR码(Google身份验证器)、通过种子或令牌的序列号注册新令牌
– 支持删除、禁用、启用和设置PIN
– 支持查看与用户相关的账号、令牌的审核日志
1.2.6 支持的用户来源
– 支持用户的来源有,平面文件、SQL数据库、LDAP、openLDAP、Active Directory或其他LDAP服务器或SCIM服务器
– 支持根据SQL用户表定义设置,有些程序包含预定义配置,如WordPress、OTRS、onwCloud和Tine 2.0
– 支持根据LDAP目录定义设置,有些程序包含预定义配置,如openLDAP和Active Directory
– 支持将一个领域组合到另外一个领域,privacyIDEA可管理无限个领域
– 支持在SQL用户存储中增删改查privacyIDEA用户
1.2.7 支持的策略
– 支持详细的行为配置(由复杂的策略模块支持)
– 支持为令牌管理、系统配置、自助服务、身份验证、授权 、注册和审核定义策略
– 支持针对某些用户、领域、管理员、管理员操作、请求的客户端、请求令牌的类型等使用策略
– 支持管理范围策略,如定义管理界面中允许管理员执行的操作(每个操作)
– 支持系统范围策略,如定义允许那个管理员配置privacyIDEA
– 支持自助服务范围策略,如定义允许用户在自助服务门户中使用它的令牌执行操作(定制从本地网络或因特网登录权限不同)
– 支持身份验证范围策略,如定义要求用户使用OTP值以外的OTP PIN登录或额外使用LDAP密码登陆
– 支持授权范围策略,如定义需要某些类型的令牌或序列号登录
– 支持注册范围策略,如定义允许用户分配的令牌数或领域包含的令牌数或注册期间的随机OTP PIN或OTP PIN强度
– 支持审计范围,如定义允许那个管理严查看审计日志
– 支持导入和导出、启用或禁用策略
1.2.8 支持的事件处理程序
– 支持响应事件的电子邮件通知
– 支持定义已处理事件不会更改原始行为
– 支持通过简单的模块设置增强时间处理
1.2.9 支持的审计
– 详细的审计日志存储到SQL数据库
– 审计条目经过数据签名和检查以防止删除(防篡改)
– 审计日志会跟踪事件状态、事件触发者、涉及的令牌、请求的客户端、执行的privacyIDEA服务器以及其他详细信息
1.2.10 支持的机器和应用
– 支持定义客户端的计算机
– 支持定义应用程序的类型(SSH、PAM、LUKS),支持分配令牌到计算机的那些程序、支持脱机身份验证
1.2.11 支持的数据库
– SQLite
– MySQL
– PostgreSQL
– Oracle
– DB2
注:令牌秘钥数据库中使用AES加密
2 最佳实践
2.1 环境配置
2.1.1 系统环境信息
HostName = privacyidea.cmdschool.org
OS = CentOS 8.x-x86_64
IP Address = 10.168.0.105
2.1.2 完成系统的基本配置
2.1.3 配置名称解析
echo '10.168.0.105 privacyidea privacyidea.cmdschool.org' >> /etc/hosts
2.2 部署DB
2.2.1 安装配置MariaDB
2.2.2 创建应用所需的库
echo 'create database privacyidea;' | mysql -u root -p echo 'grant all privileges on privacyidea.* to "privacyidea"@"localhost" identified by "privacyideapwd";' | mysql -u root -p
配置完成可使用如下名称测试你的配置,
mysql -uprivacyidea -pprivacyideapwd
2.3 部署privacyIDEA
2.3.1 安装虚拟隔离配置工具
dnf install -y python3 python3-pip pip install -y virtualenv
2.3.2 配置虚拟隔离环境
mkdir -p /opt/privacyidea virtualenv /opt/privacyidea cd /opt/privacyidea source bin/activate
另外,如果你需要反向操作,取消该虚拟环境,请使用如下命令,
rm -rf /opt/privacyidea
2.3.3 安装pip工具
cd /opt/privacyidea source bin/activate pip install -i https://pypi.tuna.tsinghua.edu.cn/simpl --upgrade pip
2.3.4 安装依赖包
cd /opt/privacyidea source bin/activate pip install -i https://pypi.tuna.tsinghua.edu.cn/simpl privacyidea==3.11.4 pip install -i https://pypi.tuna.tsinghua.edu.cn/simpl -r lib/privacyidea/requirements.txt
2.3.5 确定连接MySQL包已安装
cd /opt/privacyidea source bin/activate pip list | grep PyMySQL
2.4 配置privacyIDEA
2.4.1 配置环境变量
vim /etc/profile.d/privacyidea.sh
增加如下定义,
export PRIVACYIDEA_HOME=/opt/privacyidea export PATH=${PRIVACYIDEA_HOME}/bin:$PATH export PRIVACYIDEA_CONFIGFILE=/etc/privacyidea/pi.cfg
然后,你需要执行以下变量导入环境变量,
source /etc/profile
根据环境变量的定义,我们需要创建如下文件夹,
mkdir -p /etc/privacyidea
2.4.2 创建并定义配置文件
touch /etc/privacyidea/pi.cfg chmod 640 /etc/privacyidea/pi.cfg vim /etc/privacyidea/pi.cfg
增加如下配置,
# The realm, where users are allowed to login as administrators SUPERUSER_REALM = ['super', 'administrators'] # Your database SQLALCHEMY_DATABASE_URI = 'mysql://privacyidea:privacyideapwd@localhost/privacyidea' # This is used to encrypt the auth_token SECRET_KEY = 't0p s3cr3t' # This is used to encrypt the admin passwords PI_PEPPER = "Never know..." # This is used to encrypt the token data and token passwords PI_ENCFILE = '/etc/privacyidea/enckey' # This is used to sign the audit log PI_AUDIT_KEY_PRIVATE = '/etc/privacyidea/private.pem' PI_AUDIT_KEY_PUBLIC = '/etc/privacyidea/public.pem' # PI_AUDIT_MODULE = # PI_AUDIT_SQL_URI = # Truncate Audit entries to fit into DB columns PI_AUDIT_SQL_TRUNCATE = True # PI_LOGFILE = 'var/log/privacyidea/privacyidea.log' # PI_LOGLEVEL = 20 # PI_INIT_CHECK_HOOK = 'your.module.function' # PI_CSS = '/location/of/theme.css' # PI_UI_DEACTIVATED = True
根据环境变量的定义,我们需要创建如下文件夹,
mkdir -p /var/log/privacyidea
修改“PI_PEPPER”和“SECRET_KEY”的变量值,
PEPPER="$(tr -dc A-Za-z0-9_ </dev/urandom | head -c24)" sed -i "s~Never know...~$PEPPER~g" /etc/privacyidea/pi.cfg SECRET="$(tr -dc A-Za-z0-9_ </dev/urandom | head -c24)" sed -i "s~t0p s3cr3t~$SECRET~g" /etc/privacyidea/pi.cfg
根据配置文件的需求,我们需用使用以下命令创建变量““PI_ENCFILE””所需的文件,
pi-manage create_enckey
可见如下提示,
_ _______ _______ ___ ____(_) _____ _______ __/ _/ _ \/ __/ _ | / _ \/ __/ / |/ / _ `/ __/ // // // // / _// __ | / .__/_/ /_/|___/\_,_/\__/\_, /___/____/___/_/ |_| /_/ /___/ v3.11.4 DeprecationWarning: The command 'create_enckey' is deprecated. Traceback (most recent call last): File "/opt/privacyidea/bin/pi-manage", line 7, in sys.exit(cli()) File "/opt/privacyidea/lib/python3.9/site-packages/click/core.py", line 1157, in __call__ return self.main(*args, **kwargs) File "/opt/privacyidea/lib/python3.9/site-packages/click/core.py", line 1078, in main rv = self.invoke(ctx) File "/opt/privacyidea/lib/python3.9/site-packages/click/core.py", line 1688, in invoke return _process_result(sub_ctx.command.invoke(sub_ctx)) File "/opt/privacyidea/lib/python3.9/site-packages/click/core.py", line 1434, in invoke return ctx.invoke(self.callback, **ctx.params) File "/opt/privacyidea/lib/python3.9/site-packages/click/core.py", line 783, in invoke return __callback(*args, **kwargs) File "/opt/privacyidea/lib/python3.9/site-packages/click/decorators.py", line 33, in new_func return f(get_current_context(), *args, **kwargs) File "/opt/privacyidea/lib/python3.9/site-packages/flask/cli.py", line 383, in decorator app = ctx.ensure_object(ScriptInfo).load_app() File "/opt/privacyidea/lib/python3.9/site-packages/flask/cli.py", line 328, in load_app app: Flask | None = self.create_app() File "/opt/privacyidea/lib/python3.9/site-packages/privacyidea/cli/__init__.py", line 32, in create_silent_app app = create_app(config_name="production", silent=True) File "/opt/privacyidea/lib/python3.9/site-packages/privacyidea/app.py", line 177, in create_app db.init_app(app) File "/opt/privacyidea/lib/python3.9/site-packages/flask_sqlalchemy/extension.py", line 329, in init_app engines[key] = self._make_engine(key, options, app) File "/opt/privacyidea/lib/python3.9/site-packages/flask_sqlalchemy/extension.py", line 617, in _make_engine return sa.engine_from_config(options, prefix="") File "/opt/privacyidea/lib64/python3.9/site-packages/sqlalchemy/engine/create.py", line 739, in engine_from_config return create_engine(url, **options) File "", line 2, in create_engine File "/opt/privacyidea/lib64/python3.9/site-packages/sqlalchemy/util/deprecations.py", line 375, in warned return fn(*args, **kwargs) File "/opt/privacyidea/lib64/python3.9/site-packages/sqlalchemy/engine/create.py", line 544, in create_engine dbapi = dialect_cls.dbapi(**dbapi_args) File "/opt/privacyidea/lib64/python3.9/site-packages/sqlalchemy/dialects/mysql/mysqldb.py", line 150, in dbapi return __import__("MySQLdb") ModuleNotFoundError: No module named 'MySQLdb'
注意到“150”行的错误提示,即由于“Python 3.9”环境数据库连接模块名称变更所致,可通过如下命令修复此问题,
vim /opt/privacyidea/lib64/python3.9/site-packages/sqlalchemy/dialects/mysql/mysqldb.py
通过注解掉原来的数据库模块代码,并添加符合实际的数据库模块导入代码,详细修改如下,
#return __import__("MySQLdb") return __import__("pymysql")
修复后,重新执行可见如下提示,
_ _______ _______ ___ ____(_) _____ _______ __/ _/ _ \/ __/ _ | / _ \/ __/ / |/ / _ `/ __/ // // // // / _// __ | / .__/_/ /_/|___/\_,_/\__/\_, /___/____/___/_/ |_| /_/ /___/ v3.11.4 Encryption key written to /etc/privacyidea/enckey The file permission of /etc/privacyidea/enckey was set to 400! Please ensure, that it is owned by the right user.
根据配置文件的需求,我们需用使用以下命令创建变量“PI_AUDIT_KEY_PRIVATE”和“PI_AUDIT_KEY_PUBLIC”所需的文件,
pi-manage create_audit_keys
可见如下提示,
_ _______ _______ ___ ____(_) _____ _______ __/ _/ _ \/ __/ _ | / _ \/ __/ / |/ / _ `/ __/ // // // // / _// __ | / .__/_/ /_/|___/\_,_/\__/\_, /___/____/___/_/ |_| /_/ /___/ v3.11.4 Signing keys written to /etc/privacyidea/private.pem and /etc/privacyidea/public.pem The file permission of /etc/privacyidea/private.pem was set to 400! Please ensure, that it is owned by the right user.
根据配置文件的需求,我们需要使用如下命令创建数据库结构,
pi-manage createdb
如果收到如下错误提示,
_ _______ _______ ___ ____(_) _____ _______ __/ _/ _ \/ __/ _ | / _ \/ __/ / |/ / _ `/ __/ // // // // / _// __ | / .__/_/ /_/|___/\_,_/\__/\_, /___/____/___/_/ |_| /_/ /___/ v3.11.4 Using connect string Running online
另外便于以后更新,请使用如下命令标记当前数数据库的组织和结构版本(可选),
pi-manage db stamp head -d /opt/privacyidea/lib/privacyidea/migrations/
可见如下输出,
_ _______ _______ ___ ____(_) _____ _______ __/ _/ _ \/ __/ _ | / _ \/ __/ / |/ / _ `/ __/ // // // // / _// __ | / .__/_/ /_/|___/\_,_/\__/\_, /___/____/___/_/ |_| /_/ /___/ v3.11.4 Running online
然后,你需要使用以下命令创建一个本地的管理员账号,以下创建“admin”
pi-manage admin add admin
可见如下设置向导,
_ _______ _______ ___ ____(_) _____ _______ __/ _/ _ \/ __/ _ | / _ \/ __/ / |/ / _ `/ __/ // // // // / _// __ | / .__/_/ /_/|___/\_,_/\__/\_, /___/____/___/_/ |_| /_/ /___/ v3.11.4 Password: Repeat for confirmation: Admin admin was registered successfully.
然后,你可以使用如下命令查看运行参数,
pi-manage runserver --help
可见如下显示,
_ _______ _______ ___ ____(_) _____ _______ __/ _/ _ \/ __/ _ | / _ \/ __/ / |/ / _ `/ __/ // // // // / _// __ | / .__/_/ /_/|___/\_,_/\__/\_, /___/____/___/_/ |_| /_/ /___/ v3.11.4 Usage: pi-manage runserver [OPTIONS] (Deprecated) Run a local development server. This server is for development purposes only. It does not provide the stability, security, or performance of production WSGI servers. The reloader and debugger are enabled by default with the '--debug' option. Options: --debug / --no-debug Set debug mode. -h, --host TEXT The interface to bind to. -p, --port INTEGER The port to bind to. --cert PATH Specify a certificate file to use HTTPS. --key FILE The key file to use when specifying a certificate. --reload / --no-reload Enable or disable the reloader. By default the reloader is active if debug is enabled. --debugger / --no-debugger Enable or disable the debugger. By default the debugger is active if debug is enabled. --with-threads / --without-threads Enable or disable multithreading. --extra-files PATH Extra files that trigger a reload on change. Multiple paths are separated by ':'. --exclude-patterns PATH Files matching these fnmatch patterns will not trigger a reload on change. Multiple patterns are separated by ':'. --help Show this message and exit. This command is deprecated. Please use 'pi-manage run' instead.
然后,你可以使用如下命令手动运行服务,
pi-manage runserver -h 0.0.0.0 -p 80
可见如下显示,
_ _______ _______ ___ ____(_) _____ _______ __/ _/ _ \/ __/ _ | / _ \/ __/ / |/ / _ `/ __/ // // // // / _// __ | / .__/_/ /_/|___/\_,_/\__/\_, /___/____/___/_/ |_| /_/ /___/ v3.11.4 * Debug mode: off WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:80 * Running on http://10.168.0.22:80 Press CTRL+C to quit
2.5 配置Apache WSGI
2.5.1 安装软件包
dnf install -y httpd mod_ssl python3-mod_wsgi
2.5.2 删除ssl.conf的默认虚拟服务器配置
sed -i '/^<VirtualHost/,/<\/VirtualHost>$/d' /etc/httpd/conf.d/ssl.conf
配置修改后,请使用如下命令验证配置的语法,
httpd -t
2.5.3 启动服务并配置自启动
systemctl start httpd.service systemctl status httpd.service systemctl enable httpd.service
2.5.4 配置SELinux(可选)
semanage fcontext -a -t httpd_sys_rw_content_t "/var/log/privacyidea(/.*)?" restorecon -R /var/log/privacyidea setsebool -P httpd_can_network_connect_db 1 setsebool -P httpd_can_connect_ldap 1
2.5.5 配置运行用户和权限
useradd -r -m privacyidea -d /opt/privacyIDEA
chown -R privacyidea:root /var/log/privacyidea chown -R privacyidea:root /etc/privacyidea privacyidea-fix-access-rights -f /etc/privacyidea/pi.cfg -u privacyidea
2.5.6 部署WSGI配置
cp /opt/privacyidea/etc/privacyidea/privacyideaapp.wsgi /etc/privacyidea/
2.5.7 配置虚拟服务器
vim /etc/httpd/conf.d/privacyidea.conf
增加如下配置,
TraceEnable off ServerSignature Off ServerTokens Prod WSGIPythonHome /opt/privacyidea WSGISocketPrefix /var/run/wsgi <VirtualHost *:443> SSLEngine on SSLProtocol all -SSLv2 SSLCipherSuite DEFAULT:!EXP:!SSLv2:!DES:!IDEA:!SEED:+3DES SSLCertificateFile /etc/httpd/privacyidea.cmdschool.org.crt SSLCertificateKeyFile /etc/httpd/privacyidea.cmdschool.org.key SSLCertificateChainFile /etc/httpd/TrustedRoot.crt # The daemon is running as user 'privacyidea' # This user should have access to the encKey database encryption file WSGIDaemonProcess privacyidea python-path=/etc/privacyidea:/opt/privacyidea/lib/python3.6/site-packages processes=1 threads=15 display-name=%{GROUP} user=privacyidea WSGIProcessGroup privacyidea WSGIPassAuthorization On WSGIScriptAlias / /etc/privacyidea/privacyideaapp.wsgi DocumentRoot /var/www/privacyidea.cmdschool.org ServerName privacyidea.cmdschool.org </VirtualHost> <VirtualHost *:80> DocumentRoot /var/www/privacyidea.cmdschool.org ServerName privacyidea.cmdschool.org RewriteEngine on RewriteCond %{SERVER_PORT} !^443$ RewriteRule ^/?(.*)$ https://%{SERVER_NAME}/$1 [L,R] </VirtualHost> <Directory /var/www/privacyidea.cmdschool.org> Require all granted </Directory> <Directory /etc/privacyidea> Require all granted </Directory>
根据上面的配置,我们需要使用如下命令启动重写模块,
grep "rewrite_module modules" /etc/httpd/conf.modules.d/00-base.conf
正常有如下返回,
LoadModule rewrite_module modules/mod_rewrite.so
配置应用的证书可到腾讯云申请,详细请查阅下文,此处不再详述,
https://cloud.tencent.com/product/ssl
创建配置文件后,我们使用如下命令验证配置,
httpd -t
如果遇到如下错误提示,
AH00112: Warning: DocumentRoot [/var/www/privacyidea.cmdschool.org] does not exist AH00112: Warning: DocumentRoot [/var/www/privacyidea.cmdschool.org] does not exist Syntax OK
确认配置有效后,你需要使用如下命令重载服务使配置生效,
systemctl reload httpd.service
根据配置的需求,你可能还需要执行如下命令开放业务所需的端口,
firewall-cmd --permanent --add-service=http --add-service=https firewall-cmd --reload firewall-cmd --list-all
2.5.8 配置名称解析
notepad \Windows\System32\drivers\etc\hosts
加入如下配置,
10.168.0.105 privacyidea.cmdschool.org
注:以上为临时配置,生产环境请使用DNS配置
2.5.9 浏览器测试
https://privacyidea.cmdschool.org
注:以上账号和密码由之前步骤的“pi-manage admin add admin”命令创建
参阅文档
===================
软件版本
———-
https://pypi.org/project/privacyIDEA/
安装方法参考
——–
没有评论