2025年10月3日 星期五

OSNexus QuantaStor 社群版 試玩

https://www.osnexus.com/products/software-defined-storage

QuantaStor is a unified software-defined storage platform providing scalable file, block, and object storage across a broad spectrum of workloads. It is designed to scale up and out, simplifying storage management within a single grid. Leveraging open-source technologies like Ceph and OpenZFS, it reduces enterprise storage costs while enhancing security, performance, and uptime.

以下試玩版本為 QuantaStor v6 , 相關的 URL 如下所示

https://www.osnexus.com/

https://www.osnexus.com/downloads

https://www.osnexus.com/community-edition

https://wiki.osnexus.com/index.php?title=OSNEXUS_QuantaStor_Documentation


架構

Server IP

quantastor-a 192.168.100.211/24

quantastor-b 192.168.100.212/24

quantastor HA VIP 192.168.100.210/24

Heartbeat IP

quantastor-a 192.168.1.211/24

quantastor-b 192.168.1.212/24


重要步驟簡要說明:

(1)設定IP/DNS/NTP/HostName等基本資訊.

(2)只需在第一台建立  Storage Grid 存儲網格即可.(另第二台不需建立)

(3)接者再既有的存儲網格中新增第二台主機,隨後再建立:網站叢集/叢集環/存儲池與高可用/存儲池高可用虛擬介面(HA VIF)....

(4)試作 Sambe HA ,確定資料有正常同步複抄寫及新增跟刪除等等 














 


















2025年9月29日 星期一

NFS-Ganesha 搭配 ctdb 組成 NFS HA 實驗

 NFS-Ganesha 搭配 ctdb 組成 NFS HA 實驗  


事前導讀可參考如下 URL


https://xrcd2.blogspot.com/2022/04/glusterfs-samba.html

https://xrcd2.blogspot.com/2024/05/glusterfs-servernfs-ganesha.html



架構說明:


(1) nfs1 192.168.100.11

(2) nfs2 192.168.100.12

(3) nfs-vip  192.168.100.10

 +

(4) NFS Client  192.168.100.30



作業系統及程式安裝:


Oracle Linux 9.6 + glusterfs 11.1 + NFS-Ganesha 4.4 + ctdb 4.23.0 






[root@nfs1 /]# gluster --version

glusterfs 11.1

Repository revision: git://git.gluster.org/glusterfs.git

Copyright (c) 2006-2016 Red Hat, Inc. <https://www.gluster.org/>

GlusterFS comes with ABSOLUTELY NO WARRANTY.

It is licensed to you under your choice of the GNU Lesser

General Public License, version 3 or any later version (LGPLv3

or later), or the GNU General Public License, version 2 (GPLv2),

in all cases as published by the Free Software Foundation.



[root@nfs1 /]# gluster volume info 

 

Volume Name: nfsvolume

Type: Replicate

Volume ID: 5979bdc3-20bf-4600-bac6-ad1514459efd

Status: Started

Snapshot Count: 0

Number of Bricks: 1 x 2 = 2

Transport-type: tcp

Bricks:

Brick1: nfs1:/syncdisk

Brick2: nfs2:/syncdisk

Options Reconfigured:

cluster.granular-entry-heal: on

storage.fips-mode-rchecksum: on

transport.address-family: inet

nfs.disable: on

performance.client-io-threads: off

[root@nfs1 /]# 



[root@nfs1 /]# /usr/bin/ganesha.nfsd -v

NFS-Ganesha Release = V4.4

[root@nfs1 /]# 



[root@nfs1 /]# /usr/bin/ctdb version 

4.23.0

[root@nfs1 /]# 


這篇的重點是說明如何透過 CTDB 設定形成 NFS 服務的 HA VIP 


[root@nfs1 /]# cat /etc/ctdb/nodes 

192.168.100.11

192.168.100.12



[root@nfs1 /]# cat /etc/ctdb/public_addresses 

192.168.100.10/24 ens160



[root@nfs1 /]# ctdb status 

Number of nodes:2

pnn:0 192.168.100.11   OK (THIS NODE)

pnn:1 192.168.100.12   OK

Generation:1901971548

Size:2

hash:0 lmaster:0

hash:1 lmaster:1

Recovery mode:NORMAL (0)

Leader:1


[root@nfs1 /]# ctdb ip 

Public IPs on node 0

192.168.100.10 0



[root@nfs1 /]# ip add

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000

    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

    inet 127.0.0.1/8 scope host lo

       valid_lft forever preferred_lft forever

    inet6 ::1/128 scope host 

       valid_lft forever preferred_lft forever

2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000

    link/ether 00:0c:29:21:77:33 brd ff:ff:ff:ff:ff:ff

    altname enp3s0

    inet 192.168.100.11/24 brd 192.168.100.255 scope global noprefixroute ens160

       valid_lft forever preferred_lft forever

    inet 192.168.100.10/24 brd 192.168.100.255 scope global secondary ens160

       valid_lft forever preferred_lft forever




[root@nfs2 /]# ctdb status

Number of nodes:2

pnn:0 192.168.100.11   OK

pnn:1 192.168.100.12   OK (THIS NODE)

Generation:1901971548

Size:2

hash:0 lmaster:0

hash:1 lmaster:1

Recovery mode:NORMAL (0)

Leader:1




[root@nfs2 /]# ctdb ip

Public IPs on node 1

192.168.100.10 0

[root@nfs2 /]# 




可參考 /usr/share/ctdb/events/legacy/ 目錄內的檔自行修改所需內容



[root@nfs1 events]# cat /usr/share/ctdb/events/legacy/99.nfs-ganesha.script 

#!/bin/sh

# event script to manage nfs-ganesha in a cluster environment


[ -n "$CTDB_BASE" ] || \

    CTDB_BASE=$(d="$(dirname "$0")" && cd -P "$d/../../" && pwd)


. "${CTDB_BASE}/functions"


service_name="nfs-ganesha"


case "$1" in

    startup)

        systemctl start "$service_name"

        ;;

    shutdown)

        systemctl stop "$service_name"

        ;;

    takeip)

        systemctl try-restart "$service_name"

        ;;

    releaseip)

        systemctl stop "$service_name"

        ;;

    monitor)

        systemctl is-active --quiet "$service_name" || exit 1

        ;;

esac


exit 0



[root@nfs1 /]# ctdb event script enable legacy 10.interface


修正在  /var/log/log.ctdb ==>  nfs1 ctdb-recoverd[4893]: Assigned IP 192.168.100.10 not on an interface

該問題導致 HA VIP 無法形成??



[root@nfs1 /]# ctdb event script enable legacy 99.nfs-ganesha


[root@nfs1 /]# ctdb scriptstatus

10.interface         OK         0.027 Mon Sep 29 14:29:19 2025

99.nfs-ganesha       OK         0.006 Mon Sep 29 14:29:19 2025


====================================


nfs client 測試


[root@OL10 ~]# dnf -y install nfs-utils

[root@OL10 ~]# mount -t nfs4 192.168.100.10:/nfsha  /mnt/nfs_share

[root@OL10 ~]# df 

Filesystem            1K-blocks    Used Available Use% Mounted on

/dev/mapper/ol-root    46067712 6818824  39248888  15% /

devtmpfs                   4096       0      4096   0% /dev

tmpfs                   3833264       0   3833264   0% /dev/shm

tmpfs                   1533308    9368   1523940   1% /run

tmpfs                      1024       0      1024   0% /run/credentials/systemd-journald.service

/dev/nvme0n1p2           983040  510348    472692  52% /boot

tmpfs                      1024       0      1024   0% /run/credentials/getty@tty1.service

tmpfs                    766652      56    766596   1% /run/user/0

tmpfs                    766652      56    766596   1% /run/user/1000

192.168.100.10:/nfsha  20904960  388096  20516864   2% /mnt/nfs_share



[root@OL10 nfsshare]# cd /mnt/nfs_share/nfsshare

[root@OL10 nfsshare]# pwd

/mnt/nfs_share/nfsshare

[root@OL10 nfsshare]# ll                        

total 0

-rw-r--r-- 1 4294967294 4294967294 0 Sep 29 11:00 123.txt

[root@OL10 nfsshare]# touch abc.txt

[root@OL10 nfsshare]# ll

total 0

-rw-r--r-- 1 4294967294 4294967294 0 Sep 29 11:00 123.txt

-rw-r--r-- 1 4294967294 4294967294 0 Sep 29 14:34 abc.txt

[root@OL10 nfsshare]# 




========================================



HA 切換測試




[root@nfs2 /]# ctdb status

Number of nodes:2

pnn:0 192.168.100.11   DISCONNECTED|UNHEALTHY|INACTIVE

pnn:1 192.168.100.12   OK (THIS NODE)

Generation:839690097

Size:1

hash:0 lmaster:1

Recovery mode:NORMAL (0)

Leader:1




[root@nfs2 /]# ctdb ip

Public IPs on node 1

192.168.100.10 1




[root@nfs2 /]# ip add

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000

    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

    inet 127.0.0.1/8 scope host lo

       valid_lft forever preferred_lft forever

    inet6 ::1/128 scope host 

       valid_lft forever preferred_lft forever

2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000

    link/ether 00:0c:29:0d:0f:f6 brd ff:ff:ff:ff:ff:ff

    altname enp3s0

    inet 192.168.100.12/24 brd 192.168.100.255 scope global noprefixroute ens160

       valid_lft forever preferred_lft forever

    inet 192.168.100.10/24 brd 192.168.100.255 scope global secondary ens160

       valid_lft forever preferred_lft forever

[root@nfs2 /]# 


2025年9月20日 星期六

PrivacyIDEA RADIUS plugin Installation Notes

PrivacyIDEA  Radius 外掛安裝筆記

安裝所需軟體與安裝說明的參考連結

github url 

https://github.com/privacyidea/FreeRADIUS

https://github.com/privacyidea/FreeRADIUS/tree/master

https://github.com/privacyidea/FreeRADIUS/tree/master/config/freeradius3


Install url 

https://privacyidea.readthedocs.io/en/latest/application_plugins/rlm_perl.html


OS Oracle Linux 9.6 + freeradius 3.0.21-44.el9_6


dnf install freeradius freeradius-utils freeradius-perl* -y

dnf install perl-LWP* perl-Config*  perl-Data*   perl-Try*     perl-URI* perl-Encode* perl-JSON* -y 


rm /etc/raddb/sites-enabled/* 


rm: remove symbolic link '/etc/raddb/sites-enabled/default'? y

rm: remove symbolic link '/etc/raddb/sites-enabled/inner-tunnel'? y


rm /etc/raddb/mods-enabled/eap 


rm: remove symbolic link '/etc/raddb/mods-enabled/eap'? y


git clone https://github.com/privacyidea/FreeRADIUS.git

cp ./FreeRADIUS/config/freeradius3/privacyidea /etc/raddb/sites-enabled/

cp ./FreeRADIUS/config/freeradius3/mods-perl-privacyidea /etc/raddb/mods-enabled/

cp ./FreeRADIUS/privacyidea_radius.pm /etc/privacyidea/

cp ./FreeRADIUS/rlm_perl.ini /etc/privacyidea/

chmod 755 /etc/privacyidea/privacyidea_radius.pm

chown root.radiusd /etc/raddb/mods-enabled/mods-perl-privacyidea

chown root.radiusd /etc/raddb/sites-enabled/privacyidea 

chmod 755 /etc/raddb/mods-enabled/mods-perl-privacyidea

chmod 755 /etc/raddb/sites-enabled/privacyidea


vi /etc/raddb/mods-enabled/mods-perl-privacyidea 


==================================

perl perl-privacyidea {

    filename = /etc/privacyidea/privacyidea_radius.pm

}

================================


vi  /etc/privacyidea/rlm_perl.ini 


=========================


[Default]

URL = https://localhost/validate/check

REALM = localhost

RESCONF = Linux

SSL_CHECK = false

#SSL_CA_PATH =

#DEBUG = true


[Mapping]

serial = privacyIDEA-Serial


[Mapping user]

# The Mapping is used to add attributes to the RADIUS response.

# The value is read from the privacyIDEA response.

# In this case the content of the privacyIDEA response

#   detail->user->group

# will be written to the RADIUS response attribute "Class".

#

group = Class


===============================


vi  /etc/raddb/clients.conf 


===============================

client hostip {

        ipaddr = 192.168.100.200

        proto = udp

        secret = Passw0rd

        shortname  = radius

nas_type = other

        require_message_authenticator = no

}

=================================

systemctl start     radiusd.service 

systemctl enable      radiusd.service



確定   radiusd service 是可以被正常執行



WEB UI 操作



 















測試與驗證

Linux shell  

radtest  radius.usere 226064 192.168.100.200 0  Passw0rd









其它參考資訊 :


(A) OTP Token 設定成相同 (可視需求直改DB,修改前記得備份 )
在這裡我是做  radius 的 Token 跟 LDAP 是相同的 Token .
==>是因為 LDAP 那個 Token 在手機上被我刪了.我懶的重建 Token 

 UPDATE token SET key_enc='c86242196fcccad535696820805cc1ba195380e84ed555b412841c24b0b8b85845eb05281dd4d99dcfdbde0ce64eeaa9',key_iv='06083ff0dea2c118c45d58d89e76edda' WHERE id = 1001;






(B) Windows Debug Log 

[20-09-2025 22:02:57] [Translator.cpp:32] Translation language zh, region TW
[20-09-2025 22:02:57] [Translator.cpp:109] Can not load translation file: C:\ProgramData\Netknights GmbH\PrivacyIDEA Credential Provider\locales\zh_TW.json
[20-09-2025 22:02:57] [Translator.cpp:109] Can not load translation file: C:\ProgramData\Netknights GmbH\PrivacyIDEA Credential Provider\locales\zh.json
[20-09-2025 22:02:57] [Translator.cpp:126] Loading translation from C:\ProgramData\Netknights GmbH\PrivacyIDEA Credential Provider\locales\en.json






(C) Windows 訊息中文化.及可能會用到的機碼 


C:\ProgramData\Netknights GmbH\PrivacyIDEA Credential Provider\locales

==> zh_TW.json











Demo

用 radius.user 的 Token 登入驗證.




當然也可將  radius 登入驗證程序整合其它的網通設備..
如 Cisco Switch 或  FortiGate Firewall VPN ......

2025年9月6日 星期六

privacyIDEA 3.11.4 Installation Notes

privacyIDEA 3.11.4  安裝筆記

所需軟體的 github URL

主程式

https://github.com/privacyidea/privacyidea

可以用 curl 或 wget 去下截 程式放在 /opt/privacyidea 即可

privacyidea-3.11.4.tar.gz 

或用 git  程式放在 /opt/privacyidea 即可 

git clone https://github.com/privacyidea/privacyidea.git

以下安裝是以 privacyidea-3.11.4 這個版本做記錄的


Windows 登入驗證  (TOTP 2FA)

https://github.com/privacyidea/privacyidea-credential-provider

privacyIDEACredentialProviderSetup-v3.7.0.3.msi

這個是裝在 windows server 2022 上面


本 LAB 的運作邏輯為 privacyIDEA ( server ) --> LDAP --> Windows AD 取得 2FA 使用對象的帳號,並建立 2FA Token (TOTP)


PC --> RDP --> 已加入網域 的 Windows server (已安裝 CredentialProvider)--> 輸入 正確的 ID + PWD + 2FA Token [雙因驗證達成]



Linux --> Oracle Linux 9 + Apache + WSGI + Mariadb + Python 3.12 + privacyidea-3.11.4    


安裝筆記開始....


vi /etc/yum.repos.d/oracle-linux-ol9.repo


[ol9_codeready_builder]

name=Oracle Linux 9 CodeReady Builder ($basearch) - (Unsupported)

baseurl=https://yum$ociregion.$ocidomain/repo/OracleLinux/OL9/codeready/builder/$basearch/

gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle

gpgcheck=1

enabled=1


dnf install oracle-epel-release-el9.x86_64

dnf install python3.12-*

dnf install git openssl-devel swig openldap-devel libsodium gcc

dnf install mariadb-server mariadb httpd httpd-devel mod_ssl



alternatives --install /usr/bin/python python3 /usr/bin/python3.12 1

alternatives --install /usr/bin/python python3 /usr/bin/python3.9 2

alternatives --config python3


There are 2 programs which provide 'python3'.


  Selection    Command

-----------------------------------------------

   1           /usr/bin/python3.12

*+ 2           /usr/bin/python3.9


Enter to keep the current selection[+], or type selection number: 1

[root@OL96 ]# python -V

Python 3.12.9


 python -m ensurepip --upgrade


ln -s /usr/bin/pip3.12 /usr/bin/pip

ln -s /usr/bin/pip3.12 /usr/bin/pip3


pip3 install -U pip setuptools

pip3 install virtualenv

pip3 install  pyOpenSSL

pip3 install mysql-connector-python


useradd -r -m privacyidea -d /opt/privacyidea

usermod -aG privacyidea apache


mysql 


CREATE DATABASE pi_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

CREATE USER 'pi_user'@'localhost' IDENTIFIED BY 'password';

GRANT ALL PRIVILEGES ON pi_db.* TO 'pi_user'@'localhost';

exit




vi /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 /var/log/privacyidea

chmod 777 -R /var/log/privacyidea


virtualenv /opt/privacyidea

source /opt/privacyidea/bin/activate


cd /opt/privacyidea

pip3 install -r requirements.txt

pip3 install privacyidea==3.11.4


(privacyidea) [privacyidea@OL96 ~]#  pip3 install mod_wsgi


==> /opt/privacyidea/lib64/python3.12/site-packages/mod_wsgi/server/mod_wsgi-py312.cpython-312-x86_64-linux-gnu.so




pi-manage create_enckey

pi-manage create_audit_keys

pi-manage createdb

pi-manage admin add admin





[root@OL96 bin]# pi-manage create_enckey


             _                    _______  _______

   ___  ____(_)  _____ _______ __/  _/ _ \/ __/ _ |

  / _ \/ __/ / |/ / _ `/ __/ // // // // / _// __ |

 / .__/_/ /_/|___/\_,_/\__/\_, /___/____/___/_/ |_|

/_/                       /___/

                                            v3.11.4

.....

.....

......



[root@OL96 bin]# pi-manage createdb


             _                    _______  _______

   ___  ____(_)  _____ _______ __/  _/ _ \/ __/ _ |

  / _ \/ __/ / |/ / _ `/ __/ // // // // / _// __ |

 / .__/_/ /_/|___/\_,_/\__/\_, /___/____/___/_/ |_|

/_/                       /___/

                                            v3.11.4


DeprecationWarning: The command 'createdb' is deprecated.

Using connect string <SQLAlchemy mysql+pymysql://pi_user:password@localhost/pi_db......                                                                                                                                                             b?charset=utf8mb4>

Running online


[root@OL96 bin]# mysql

Welcome to the MariaDB monitor.  Commands end with ; or \g.

Your MariaDB connection id is 8

Server version: 10.5.27-MariaDB MariaDB Server


Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.


Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.



MariaDB [(none)]> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| mysql              |

| performance_schema |

| pi_db              |

+--------------------+

....


MariaDB [(none)]> use pi_db;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A


Database changed


MariaDB [pi_db]> show tables;

+-------------------------+

| Tables_in_pi_db         |

+-------------------------+

| admin                   |

| alembic_version         |

| audit_seq               |

| authcache               |

| authcache_seq           |

| caconfig_seq            |

| caconnector             |

| caconnector_seq         |

| caconnectorconfig       |

| challenge               |

| challenge_seq           |

| clientapp_seq           |

| clientapplication       |

......

.....

....


MariaDB [pi_db]> exit


[root@OL96 bin]# pi-manage admin add admin


             _                    _______  _______

   ___  ____(_)  _____ _______ __/  _/ _ \/ __/ _ |

  / _ \/ __/ / |/ / _ `/ __/ // // // // / _// __ |

 / .__/_/ /_/|___/\_,_/\__/\_, /___/____/___/_/ |_|

/_/                       /___/

                                            v3.11.4


Password:

Repeat for confirmation:

Admin admin was registered successfully.

[root@OL96 bin]#



[root@OL96 ~]# cat /etc/privacyidea/pi.cfg

import logging

# The realm, where users are allowed to login as administrators

SUPERUSER_REALM = ['super', 'administrators']

# Your database

SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://pi_user:password@localhost/pi_db'

# This is used to encrypt the auth_token

# This is used to encrypt the admin passwords

# 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_SQL_TRUNCATE = True

# The Class for managing the SQL connection pool

PI_ENGINE_REGISTRY_CLASS = "shared"

PI_AUDIT_POOL_SIZE = 20

#PI_LOGFILE = '/tmp/privacyidea.log'

PI_LOGFILE = '/var/log/privacyidea/privacyidea.log'

PI_LOGLEVEL = logging.INFO

PI_PEPPER = 'v9EW6gt1SGEHgpBQpznTmPtn'

SECRET_KEY = 'BnLflBoiKfc9HOJyFR2agAv9'



[root@OL96 ~]# cat /etc/privacyidea/privacyideaapp.wsgi

import sys

sys.stdout = sys.stderr

from privacyidea.app import create_app

application = create_app(config_name="production", config_file="/etc/privacyidea                                                                                                                                                             /pi.cfg")

[root@OL96 ~]#


[root@OL96 privacyidea]# pwd

/etc/privacyidea

[root@OL96 privacyidea]# ll

total 20

-rwxr-xr-x 1 privacyidea apache   96 Sep  6 10:51 enckey

-rwxr-xr-x 1 privacyidea apache  881 Sep  6 10:49 pi.cfg

-rwxr-xr-x 1 privacyidea apache  164 Sep  6 10:48 privacyideaapp.wsgi

-rw-r--r-- 1 privacyidea apache 1679 Sep  6 10:50 private.pem

-rw-r--r-- 1 privacyidea apache  451 Sep  6 10:50 public.pem

[root@OL96 privacyidea]#


[root@OL96 privacyidea]# pwd

/opt/privacyidea

[root@OL96 privacyidea]# ll

total 116

drwxr-xr-x 5 privacyidea privacyidea    82 Jul  2 19:56 authmodules

-rwxr-xr-x 1 privacyidea privacyidea  9101 Jul  2 19:56 AUTHORS.md

drwxr-xr-x 3 privacyidea privacyidea  4096 Sep  6 10:44 bin

-rwxr-xr-x 1 privacyidea privacyidea   194 Sep  6 10:24 CACHEDIR.TAG

drwxr-xr-x 9 privacyidea privacyidea   188 Jul  2 19:56 deploy

drwxr-xr-x 3 privacyidea privacyidea    25 Sep  6 10:28 etc

drwxr-xr-x 3 privacyidea privacyidea    18 Sep  6 10:28 include

drwxr-xr-x 4 privacyidea privacyidea    43 Sep  6 10:28 lib

drwxr-xr-x 3 privacyidea privacyidea    24 Sep  6 10:24 lib64

-rwxr-xr-x 1 privacyidea privacyidea 32387 Jul  2 19:56 LICENSE

-rwxr-xr-x 1 privacyidea privacyidea   352 Jul  2 19:56 MANIFEST.in

drwxr-xr-x 3 privacyidea privacyidea    91 Jul  2 19:56 migrations

-rwxr-xr-x 1 privacyidea privacyidea 11480 Jul  2 19:56 PKG-INFO

drwxr-xr-x 8 privacyidea privacyidea   190 Jul  2 19:56 privacyidea

drwxr-xr-x 2 privacyidea privacyidea   154 Jul  2 19:56 privacyIDEA.egg-info

-rwxr-xr-x 1 privacyidea privacyidea   210 Sep  6 10:24 pyvenv.cfg

-rwxr-xr-x 1 privacyidea privacyidea  8603 Jul  2 19:56 README.rst

-rwxr-xr-x 1 privacyidea privacyidea  3646 Jul  2 19:56 requirements.txt

-rwxr-xr-x 1 privacyidea privacyidea    38 Jul  2 19:56 setup.cfg

-rwxr-xr-x 1 privacyidea privacyidea  5296 Jul  2 19:56 setup.py

drwxr-xr-x 3 privacyidea privacyidea    17 Sep  6 10:28 share

drwxr-xr-x 4 privacyidea privacyidea  8192 Jul  2 19:56 tests

drwxr-xr-x 2 privacyidea privacyidea  4096 Jul  2 19:56 tools

[root@OL96 privacyidea]#


[root@OL96 bin]# pwd

/opt/privacyidea/bin

[root@OL96 bin]# ll

total 304

-rwxr-xr-x 1 privacyidea privacyidea  2901 Sep  6 10:24 activate

-rwxr-xr-x 1 privacyidea privacyidea  2056 Sep  6 10:24 activate.csh

-rwxr-xr-x 1 privacyidea privacyidea  3744 Sep  6 10:24 activate.fish

-rwxr-xr-x 1 privacyidea privacyidea  2837 Sep  6 10:24 activate.nu

-rwxr-xr-x 1 privacyidea privacyidea  2657 Sep  6 10:24 activate.ps1

-rwxr-xr-x 1 privacyidea privacyidea  1321 Sep  6 10:24 activate_this.py

-rwxr-xr-x 1 privacyidea privacyidea   197 Sep  6 10:40 alembic

-rwxr-xr-x 1 privacyidea privacyidea   193 Sep  6 10:40 cbor2

-rwxr-xr-x 1 privacyidea privacyidea   750 Sep  6 10:28 creategoogleauthenticator-file

-rwxr-xr-x 1 privacyidea privacyidea   192 Sep  6 10:40 flask

-rwxr-xr-x 1 privacyidea privacyidea  1458 Sep  6 10:28 getgooglecodes

-rwxr-xr-x 1 privacyidea privacyidea   223 Sep  6 10:40 huey_consumer

-rwxr-xr-x 1 privacyidea privacyidea  1757 Sep  6 10:40 huey_consumer.py

-rwxr-xr-x 1 privacyidea privacyidea   197 Sep  6 10:40 mako-render

-rwxr-xr-x 1 privacyidea privacyidea   198 Sep  6 10:33 mod_wsgi-express

-rwxr-xr-x 1 privacyidea privacyidea   194 Sep  6 10:28 netaddr

-rwxr-xr-x 1 privacyidea privacyidea   217 Sep  6 10:40 normalizer

-rwxr-xr-x 1 privacyidea privacyidea   205 Sep  6 10:28 pi-manage

-rwxr-xr-x 1 privacyidea privacyidea   236 Sep  6 10:24 pip

-rwxr-xr-x 1 privacyidea privacyidea   236 Sep  6 10:24 pip3

-rwxr-xr-x 1 privacyidea privacyidea   236 Sep  6 10:24 pip-3.12

-rwxr-xr-x 1 privacyidea privacyidea   236 Sep  6 10:24 pip3.12

-rwxr-xr-x 1 privacyidea privacyidea   211 Sep  6 10:28 pi-tokenjanitor

-rwxr-xr-x 1 privacyidea privacyidea  2566 Sep  6 10:28 privacyidea-authorizedkeys

-rwxr-xr-x 1 privacyidea privacyidea  1748 Sep  6 10:28 privacyidea-convert-base32.py

-rwxr-xr-x 1 privacyidea privacyidea  2876 Sep  6 10:28 privacyidea-convert-token

-rwxr-xr-x 1 privacyidea privacyidea  3230 Sep  6 10:28 privacyidea-convert-xml-to-csv

-rwxr-xr-x 1 privacyidea privacyidea  2422 Sep  6 10:28 privacyidea-create-ad-users

-rwxr-xr-x 1 privacyidea privacyidea  1934 Sep  6 10:28 privacyidea-create-certificate

-rwxr-xr-x 1 privacyidea privacyidea  1907 Sep  6 10:28 privacyidea-create-pwidresolver-user

-rwxr-xr-x 1 privacyidea privacyidea  1529 Sep  6 10:28 privacyidea-create-sqlidresolver-user

-rwxr-xr-x 1 privacyidea privacyidea   914 Sep  6 10:28 privacyidea-create-userdb

-rwxr-xr-x 1 privacyidea privacyidea   207 Sep  6 10:28 privacyidea-cron

-rwxr-xr-x 1 privacyidea privacyidea  8408 Sep  6 10:28 privacyidea-diag

-rwxr-xr-x 1 privacyidea privacyidea   232 Sep  6 10:28 privacyidea-expired-users

-rwxr-xr-x 1 privacyidea privacyidea  4511 Sep  6 10:28 privacyidea-export-linotp-counter.py

-rwxr-xr-x 1 privacyidea privacyidea  1353 Sep  6 10:28 privacyidea-export-privacyidea-counter.py

-rwxr-xr-x 1 privacyidea privacyidea  3735 Sep  6 10:28 privacyidea-fetchssh

-rwxr-xr-x 1 privacyidea privacyidea  2453 Sep  6 10:28 privacyidea-fix-access-rights

-rwxr-xr-x 1 privacyidea privacyidea   227 Sep  6 10:28 privacyidea-get-serial

-rwxr-xr-x 1 privacyidea privacyidea   220 Sep  6 10:28 privacyidea-get-unused-tokens

-rwxr-xr-x 1 privacyidea privacyidea   302 Sep  6 10:46 privacyidea.log

-rwxr-xr-x 1 privacyidea privacyidea 25697 Sep  6 10:28 privacyidea-migrate-linotp.py

-rwxr-xr-x 1 privacyidea privacyidea  2539 Sep  6 10:28 privacyidea-pip-update

-rwxr-xr-x 1 privacyidea privacyidea  5793 Sep  6 10:28 privacyidea-queue-huey

-rwxr-xr-x 1 privacyidea privacyidea   631 Sep  6 10:28 privacyidea-schema-upgrade

-rwxr-xr-x 1 privacyidea privacyidea   213 Sep  6 10:28 privacyidea-standalone

-rwxr-xr-x 1 privacyidea privacyidea  8134 Sep  6 10:28 privacyidea-sync-owncloud.py

-rwxr-xr-x 1 privacyidea privacyidea   220 Sep  6 10:28 privacyidea-token-janitor

-rwxr-xr-x 1 privacyidea privacyidea  3816 Sep  6 10:28 privacyidea-update-counter.py

-rwxr-xr-x 1 privacyidea privacyidea  5420 Sep  6 10:28 privacyidea-update-linotp-counter.py

-rwxr-xr-x 1 privacyidea privacyidea  5473 Sep  6 10:28 privacyidea-user-action

-rwxr-xr-x 1 privacyidea privacyidea   236 Sep  6 10:28 privacyidea-usercache-cleanup

-rwxr-xr-x 1 privacyidea privacyidea   206 Sep  6 10:40 pybabel

drwxr-xr-x 2 privacyidea privacyidea  4096 Sep  6 10:40 __pycache__

-rwxr-xr-x 1 privacyidea privacyidea   196 Sep  6 10:40 pyrsa-decrypt

-rwxr-xr-x 1 privacyidea privacyidea   196 Sep  6 10:40 pyrsa-encrypt

-rwxr-xr-x 1 privacyidea privacyidea   194 Sep  6 10:40 pyrsa-keygen

-rwxr-xr-x 1 privacyidea privacyidea   217 Sep  6 10:40 pyrsa-priv2pub

-rwxr-xr-x 1 privacyidea privacyidea   190 Sep  6 10:40 pyrsa-sign

-rwxr-xr-x 1 privacyidea privacyidea   194 Sep  6 10:40 pyrsa-verify

lrwxrwxrwx 1 privacyidea privacyidea    19 Sep  6 10:24 python -> /usr/bin/python3.12

lrwxrwxrwx 1 privacyidea privacyidea     6 Sep  6 10:24 python3 -> python

lrwxrwxrwx 1 privacyidea privacyidea     6 Sep  6 10:24 python3.12 -> python

-rwxr-xr-x 1 privacyidea privacyidea  3133 Sep  6 10:28 reset-privacyidea

-rwxr-xr-x 1 privacyidea privacyidea   192 Sep  6 10:40 segno

[root@OL96 bin]#


[root@OL96 conf.d]# pwd

/etc/httpd/conf.d

[root@OL96 conf.d]# ll

total 36

-rw-r--r-- 1 root root 2916 Sep  2 16:02 autoindex.conf.bak

-rwxr-xr-x 1 root root 4409 Sep  6 12:00 privacyidea.conf

-rw-r--r-- 1 root root  400 Sep  2 16:02 README

-rw-r--r-- 1 root root 8720 Sep  2 16:00 ssl.conf.bak

-rw-r--r-- 1 root root 1252 Sep  2 16:00 userdir.conf.bak

-rw-r--r-- 1 root root  653 Sep  2 16:00 welcome.conf.bak

[root@OL96 conf.d]#


===> privacyidea.conf 


可自行參考   # cat /opt/privacyidea/deploy/apache/sites-available/privacyidea.conf


SSL 憑證可以用系統的即可,就是用預設的 ssl.conf 內所設定的


SSLCertificateFile /etc/pki/tls/certs/localhost.crt

SSLCertificateKeyFile /etc/pki/tls/private/localhost.key



可以需求或環境抄改如下設定,最簡單的方式就可將以下文件 + ssl.conf 整併也可.. 


[root@OL96 sites-available]# cat /opt/privacyidea/deploy/apache/sites-available/privacyidea.conf

<VirtualHost _default_:443>

        ServerAdmin webmaster@localhost

        # You might want to change this

        ServerName localhost


        DocumentRoot /var/www

        <Directory />

                # For Apache 2.4 you need to set this:

                Require all granted

                Options FollowSymLinks

                AllowOverride None

        </Directory>


        # Yubico servers use /wsapi/2.0/verify as the path in the

        # validation URL. Some tools (e.g. Kolab 2fa) let the

        # user/admin change the api host, but not the rest of

        # the URL. Uncomment the following two lines to reroute

        # the api URL internally to privacyideas /ttype/yubikey.

        #RewriteEngine  on

        #RewriteRule    "^/wsapi/2.0/verify"  "/ttype/yubikey" [PT]


        # We can run several instances on different paths with different configurations

        WSGIScriptAlias /      /etc/privacyidea/privacyideaapp.wsgi

        #WSGIScriptAlias /instance1      /home/cornelius/src/privacyidea/deploy/privacyideaapp1.wsgi

        #WSGIScriptAlias /instance2      /home/cornelius/src/privacyidea/deploy/privacyideaapp2.wsgi

        #WSGIScriptAlias /instance3      /home/cornelius/src/privacyidea/deploy/privacyideaapp3.wsgi

        #

        # The daemon is running as user 'privacyidea'

        # This user should have access to the encKey database encryption file

        WSGIDaemonProcess privacyidea processes=1 threads=15 display-name=%{GROUP} user=privacyidea

        WSGIProcessGroup privacyidea

        WSGIPassAuthorization On


        ErrorLog /var/log/apache2/error.log


        LogLevel warn

        # Do not use %q! This will reveal all parameters, including setting PINs and Keys!

        # Using SSL_CLINET_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\"" privacyIDEA

        CustomLog /var/log/apache2/ssl_access.log privacyIDEA


.....

....

....




優化 WSGI 


# cp /opt/privacyidea/lib64/python3.12/site-packages/mod_wsgi/server/mod_wsgi-py312.cpython-312-x86_64-linux-gnu.so /etc/httpd/modules/

# vi /etc/httpd/conf.modules.d/10-wsgi-python3.conf



[root@Oracle9]# cat /etc/httpd/conf.modules.d/10-wsgi-python3.conf 


# NOTE: mod_wsgi_python3 can not coexist in the same apache process as

# mod_wsgi (python2).  Only load if mod_wsgi is not already loaded.


<IfModule !wsgi_module>


    #LoadModule wsgi_module modules/mod_wsgi_python3.so


    LoadModule wsgi_module modules/mod_wsgi-py312.cpython-312-x86_64-linux-gnu.so


</IfModule>



#systemctl restart  httpd



優化成果


httpd log 

....

........ Apache/2.4.62 (Oracle Linux Server) OpenSSL/3.2.2 mod_wsgi/5.0.2 Python/3.12 configured -- resuming normal operations

....


其它參考資訊


==> privacyideaapp.wsgi


[root@OL96 apache]# cat /opt/privacyidea/deploy/apache/privacyideaapp.wsgi

import sys

sys.stdout = sys.stderr

from privacyidea.app import create_app

# Now we can select the config file:

application = create_app(config_name="production", config_file="/etc/privacyidea/pi.cfg")


==> pi.cfg


[root@OL96 deploy]# cat /opt/privacyidea/deploy/pi.cfg

import logging

# The realm, where users are allowed to login as administrators

SUPERUSER_REALM = ['super']

# Your database

SQLALCHEMY_DATABASE_URI = 'sqlite:////home/cornelius/src/privacyidea/data.sqlite'

# 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 = '/home/cornelius/src/privacyidea/enckey'

# This is the dummy base class

#PI_AUDIT_MODULE = 'privacyidea.lib.auditmodules.base'

# This is the default

#PI_AUDIT_MODULE = 'privacyidea.lib.auditmodules.sqlaudit'

# This is used to sign the audit log

PI_AUDIT_KEY_PRIVATE = '/home/cornelius/src/privacyidea/private.pem'

PI_AUDIT_KEY_PUBLIC = '/home/cornelius/src/privacyidea/public.pem'

PI_AUDIT_SQL_TRUNCATE = True

# The Class for managing the SQL connection pool

PI_ENGINE_REGISTRY_CLASS = "shared"

PI_AUDIT_POOL_SIZE = 20


PI_LOGLEVEL = logging.INFO

# Extend the list of keys that will identify a machine to receive offline data

#OFFLINE_MACHINE_KEYS = ["myCustomKey", "myOtherKey"]

[root@OL96 deploy]#


Demo





進階設定可過濾特定的 Group

Search Filter  ==> (sAMAccountName=*)(&(objectCategory=person)(memberOf=cn=erp,ou=it,dc=vlab,dc=local))



















2025年8月2日 星期六

X-Forwarded-For (XFF) LAB

以下實驗在於 X-Forwarded-For (XFF) 測試,驗證透過開源的CDN 軟體 Varnish

加上 FortiGate 的 Virtual server load balance 機制.取得真實 Client IP .

Varnish HTTP Cache 

https://www.varnish-cache.org


實驗架構



連線流程


Client [192.168.100.0/24] (設定 hosts 192.168.100.20 wps.cdn.tw ) 

--> CDN IP (192.168.100.20) --> 原站 IP [192.168.100.10] (FTG SLB VIP)

-->  FTG Firewall (192.168.100.125/192.168.1.1)

--> SLB Member (RealServer IP 192.168.1.11 or 12)

--> Nginx log  取得真實 Client IP


重要設定

[root@CDN ~]#  cat /etc/varnish/default.vcl

vcl 4.0;


backend default {

    .host = "127.0.0.1";

    .port = "8080";

}


acl purge {

    "localhost";

    "127.0.0.1";

}


sub vcl_recv {


    if (req.method == "PURGE") {

        if (!client.ip ~ purge) {

            return(synth(405, "DENY"));

        }

        return (purge);

    }


    if (req.url ~ "\.(gif|jpg|jpeg|swf|ttf|css|js|flv|mp3|mp4|pdf|ico|png)(\?.*|)$") {

        unset req.http.cookie;

    }

}


sub vcl_pipe {

    return (pipe);

}


sub vcl_pass {

    return (fetch);

}


sub vcl_backend_response {

.............


[root@CDN ~]#  cat /etc/nginx/nginx.conf


.....


server {

  listen 80;

  server_name wps.cdn.tw;

  port_in_redirect off;

  add_header Strict-Transport-Security "max-age=31536000;";

  add_header X-Content-Type-Options nosniff;

  location / {

    proxy_pass http://127.0.0.1:6081;

    proxy_set_header Host $http_host;

    proxy_set_header X-Forwarded-Host $http_host;

    proxy_set_header X-Real-IP $remote_addr;

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    proxy_set_header X-Forwarded-Proto https;

    proxy_set_header HTTPS "on";

  }


}


server {

  listen 8080;

  server_name wps.cdn.tw;

  location / {

    proxy_pass http://192.168.100.10;

    proxy_set_header  Host $http_host;


.....



[root@CDN ~]#  dnf info varnish.x86_64

Last metadata expiration check: 1:15:24 ago on Sat 02 Aug 2025 01:18:24 PM CST.

Installed Packages

Name         : varnish

Version      : 6.6.2

Release      : 6.el9_6.1

Architecture : x86_64

Size         : 3.0 M

Source       : varnish-6.6.2-6.el9_6.1.src.rpm

Repository   : @System

From repo    : ol9_appstream

Summary      : High-performance HTTP accelerator

URL          : https://www.varnish-cache.org/

License      : BSD

Description  : This is Varnish Cache, a high-performance HTTP accelerator.

             :

             : Varnish Cache stores web pages in memory so web servers don’t have to

             : create the same web page over and over again. Varnish Cache serves

             : pages much faster than any application server; giving the website a

             : significant speed up.

             :

             : Documentation wiki and additional information about Varnish Cache is

             : available on: https://www.varnish-cache.org/


RealServer 上 Nginx log 設定


log_format  main  '$http_x_forwarded_for |

                    $http_x_real_ip |

                    $remote_addr - $remote_user [$time_local] "$request" '

                   '$status $body_bytes_sent "$http_referer" '

                   '"$http_user_agent" "$http_x_forwarded_for"';


Demo














2025年7月18日 星期五

PaloAlto Dual ISP with ECMP testing

 














tracert (Trace Route)





show routing route ecmp yes




其它補充:

如果要指定某一個 Source IP / Range ..走特定的 WAN x / ISP x ,
就同一般的[網通設備]一樣.
使用 政策路由 Policy-Based Route [PBR] 設定即可,
等同於 PaloAlto  的  Policy Based Forwarding  [PBF] 設定


判斷邏輯為: 
檢查是否有 PBF Rule -->  有命中則 依 PBF 決定路由
若沒命中則視  Routing Table  (可用 ECMP ) 決定其路由