2025年9月23日 星期二

Debian pam_exec.so 筆記

編輯 /etc/pam.d/common-auth
auth    [success=2 default=ignore]      pam_exec.so quiet debug expose_authtok log=/tmp/pam_exec.log /etc/libnss_shim/auth.sh
auth    [success=1 default=ignore]      pam_unix.so nullok try_first_pass
# here's the fallback if no module succeeds
auth    requisite                       pam_deny.so

編輯 /etc/libnss_shim/auth.sh
#!/bin/bash
set >/tmp/a
read pwd
echo pwd=$pwd PAM_USER=$PAM_USER >>/tmp/a
getent passwd -s files ${PAM_USER}>/dev/null && { echo local:${PAM_USER};exit 1; }

echo $PAM_USER login ok
exit 0;

2025年9月22日 星期一

debian 13 安裝 Generic Shell Script Compiler

git clone https://github.com/neurobin/shc
cd shc
./configure
./autogen.sh
make
cp src/shc /usr/local/bin/

2025年9月19日 星期五

Debian 13 安裝Apache2 modsecurity

安裝
apt install -y apache2  libapache2-mod-security2 

編輯 /etc/apache2/sites-enabled/000-default.conf 加入
SecRuleEngine On

相關檔案
/etc/apache2/mods-enabled/security2.conf
/etc/apache2/mods-enabled/security2.load 

/var/cache/modsecurity
/etc/modsecurity/*.conf
/usr/share/modsecurity-crs/*.load

Debian 13 安裝 nginx php

 apt install nginx php-fpm

編輯 /etc/nginx/sites-enabled/default
location ~ \.php$ {
                include snippets/fastcgi-php.conf;
        #
        #       # With php-fpm (or other unix sockets):
        #       fastcgi_pass unix:/run/php/php7.4-fpm.sock;
                fastcgi_pass unix:/run/php/php8.4-fpm.sock;
        #       # With php-cgi (or other tcp sockets):
        #       fastcgi_pass 127.0.0.1:9000;
        }

2025年9月18日 星期四

Squid for SSH tunneling

SQUID 設定加入
acl SSL_ports port 22
acl Safe_ports port 22 # ssh/sftp
http_access allow CONNECT SSL_ports

使用方式
ssh  user@sshserver-ip -o "ProxyCommand /usr/bin/nc -X connect -x squid_ip:3128 %h %p"

編輯 ~/.ssh/config
Host target_ssh_server
Hostname actual_target_ip_or_hostname
User your_username
ProxyCommand /usr/bin/nc -X connect -x squid_proxy_ip:3128 %h %p
# Or with corkscrew:
# ProxyCommand corkscrew squid_proxy_ip 3128 %h %p

2025年9月9日 星期二

Debian 13 使用 sssd 加入 domain

apt install -y adcli realmd krb5-user samba-common-bin samba-libs samba-dsdb-modules sssd sssd-tools libnss-sss libpam-sss packagekit polkitd  pkexec

/etc/sssd/sssd.conf  設定檔
[sssd]
domains = ad.example
config_file_version = 2
services = nss, pam

[domain/tw.example]
ad_domain = ad.example
krb5_realm = AD.EXAMPLE
realmd_tags = manages-system joined-with-samba
cache_credentials = True
id_provider = ad
krb5_store_password_if_offline = True
default_shell = /bin/bash
ldap_id_mapping = True
use_fully_qualified_names = False    #登入時,不需輸入網域
fallback_homedir = /home/%d/%u       #自動建立的 home 目錄不會加上 @DomainName
access_provider = ad
enumerate = true       #可 使用 getent 查詢帳號資訊
ad_gpo_map_interactive = +xrdp-sesman

編輯 /etc/pam.d/common-session
# add to the end if need (create home directory automatically at initial login)
session optional        pam_mkhomedir.so skel=/etc/skel umask=077

2025年9月2日 星期二

PHP FILETIME UNIX Time 轉換

UNIX時間採用世界標準時1970年1月1日00:00:00開始的秒數(不考慮閏秒)。
Windows API使用SYSTEMTIME表示年月日時分秒毫秒;
FILETIME表示自世界標準時1601年1月1日00:00:00開始的100奈秒為單位

 <?php
function ftime2utime($filetime_value){
  // 1. 轉換為秒 ( FILETIME單位是100奈秒 )
  $filetime_seconds = $filetime_value / 10000000;

  // 2. 減去UNIX紀元的偏移量 (1970年1月1日到1601年1月1日)
  $unix_timestamp = $filetime_seconds - 11644473600;

  // 3. 使用date()函數格式化時間戳
  $formatted_time = date('Y-m-d H:i:s', $unix_timestamp);

  echo "FILETIME : " . $filetime_value . "\n";
  echo "UNIX TIME: " . $unix_timestamp . "\n";
  echo "format   : " . $formatted_time . "\n";
}

function utime2ftime($unixTimestamp){
  // 计算自 1601 年以来的 100 纳秒间隔
  // 11644473600 是 1601 年 1 月 1 日 UTC 到 1970 年 1 月 1 日 UTC 的秒数 [1]
  // 10,000,000 将秒转换为 100 纳秒间隔 [1]
  $filetime = ($unixTimestamp + 11644473600) * 10000000;

  echo "Unix Timestamp: " . $unixTimestamp . "\n";
  echo "FILETIME (Hex): " . sprintf('%x', $filetime) . "\n";
  echo "FILETIME: ". $filetime . "\n";
}

$unixTimestamp = 1759420800;
utime2ftime($unixTimestamp);

echo "\n";
$filetime_value = 134038944000000000;
ftime2utime($filetime_value);
?>

2025年9月1日 星期一

debian Linux 查詢系統狀況指令

top
htop
ac apt install  act
atop apt install atop
btop apt install btop
s-tui apt install s-tui

vmstat apt install sysstat

lsof
iotop apt install iotop
iostat apt install sysstat

tcpdump
netstat
iptraf
nethogs apt install nethogs
iftop apt install iftop
netdata apt install netdata
arpwatch apt install arpwatch

nmon apt install nmon

XRDP 筆記

連線管理程式
 xrdp-sesadmin
loginctl list-sessions

相關日誌
journalctl -xeu xrdp.service
journalctl -xeu xrdp-sesman.service

/var/log/xrdp.log
/var/log/xrdp-sesman.log

Debian 使用 Google Authenticator-based Two-Factor Authentication (2FA)

安裝
apt install libpam-google-authenticator

編輯/etc/pam.d/sshd  加入
auth required pam_google_authenticator.so nullok

編輯 /etc/ssh/sshd_config 加入
ChallengeResponseAuthentication yes
KbdInteractiveAuthentication yes

執行
google-authenticator

參考文件
https://github.com/google/google-authenticator-libpam
qrencode -t ansiutf8 `cat .google_authenticator `

Windows AD accountExpires屬性

建立帳戶時,帳戶一開始會設定為 永不過期。
accountExpires 屬性預設值 9223372036854775807 ,對應 64 位帶正負號整數的最大值
帳戶設定到期日, accountExpires 設定為到期日的 FILETIME 值
帳戶設定到期時間為永不過期, accountExpires 設定為 0 

PHP 查詢 Windows AD objectGUID objectSid (string fromat)

 <?php
function objectSid($binary_sid) {
    if(strlen(decbin(~0)) == 64)  //64bit PHP
    {
        // Get revision, indentifier, authority
        $parts = unpack('Crev/x/nidhigh/Nidlow', $binary_sid);
        // Set revision, indentifier, authority
        $sid = sprintf('S-%u-%d',  $parts['rev'], ($parts['idhigh']<<32) + $parts['idlow']);
        // Translate domain
        $parts = unpack('x8/V*', $binary_sid);
        // Append if parts exists
        if ($parts) $sid .= '-';
        // Join all
        return $sid.= join('-', $parts);
    }
     //32bit PHP
    $sid = 'S-';
    $sidinhex = str_split(bin2hex($binary_sid), 2);
    // Byte 0 = Revision Level
    $sid = $sid.hexdec($sidinhex[0]).'-';
    // Byte 1-7 = 48 Bit Authority
    $sid = $sid.hexdec($sidinhex[6].$sidinhex[5].$sidinhex[4].$sidinhex[3].$sidinhex[2].$sidinhex[1]);
    // Byte 8 count of sub authorities - Get number of sub-authorities
    $subauths = hexdec($sidinhex[7]);
    //Loop through Sub Authorities
    for($i = 0; $i < $subauths; $i++) {
        $start = 8 + (4 * $i);
        // X amount of 32Bit (4 Byte) Sub Authorities
        $sid = $sid.'-'.hexdec($sidinhex[$start+3].$sidinhex[$start+2].$sidinhex[$start+1].$sidinhex[$start]);
    }
    return $sid;
}

function objectGUID($binaryGuid) {
    $hexGuid = bin2hex($binaryGuid);
    // Reorder and format according to standard GUID representation
    $hex1 = substr($hexGuid, 6, 2) . substr($hexGuid, 4, 2) . substr($hexGuid, 2, 2) . substr($hexGuid, 0, 2);
    $hex2 = substr($hexGuid, 10, 2) . substr($hexGuid, 8, 2);
    $hex3 = substr($hexGuid, 14, 2) . substr($hexGuid, 12, 2);
    $hex4 = substr($hexGuid, 16, 4);
    $hex5 = substr($hexGuid, 20, 12);
    return sprintf('%s-%s-%s-%s-%s', $hex1, $hex2, $hex3, $hex4, $hex5);
}

$user = 'user1';         //設定欲認證的帳號名稱
$ldappass = 'p@ssw0rd';  //設定欲認證的帳號密碼
$domain = 'test.loc';   //設定網域名稱

putenv('LDAPTLS_REQCERT=allow');
$ldapconn = @ldap_connect("ldaps://" . $domain) or die("無法連接至 $domain");
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0);

if ($ldapconn) { // binding to ldap server
    $ldapbind = @ldap_bind($ldapconn, $user . '@' . $domain, $ldappass);
    if ($ldapbind) {  // verify binding
        $result = @ldap_search($ldapconn, sprintf("dc=%s", (str_replace(".", ",dc=", $domain))), "(sAMAccountName=$user)");

        if($result==false) echo "認證失敗";
        else {
          $entries = ldap_get_entries($ldapconn, $result);
          $results2 = ldap_search($ldapconn, sprintf("dc=%s", (str_replace(".", ",dc=", $domain))),"(&(objectclass=group)(objectsid=*))", array("cn", "objectguid"));
          $entries2 = ldap_get_entries($ldapconn, $results2);

          for ($i=1; $i<$entries2['count']; $i++)
            echo $entries2[$i]['cn'][0] . "\n" . objectGUID($entries2[$i]['objectguid'][0]) . "\n" . objectSid($entries2[$i]['objectsid'][0]) . "\n\n";
        }
    } else echo "認證失敗...";
}
?>