使用 certbot 申請 Let’s Encrypt Wildcard 憑證

系統: Centos 7
需求: 包含自行管理DNS的網域(bind)以及免費 no-ip網域, 若為其它代管業者可以到certbot查詢是否有範本或plugin.

安裝

在提供服務的主機

yum install certbot
yum install python2-pip

DNS若為自行管理, 需要安裝 certbot-dns-rfc2136 PLUGIN以自動更新DNS TXT RECORD讓 Let’s Encrypt 確認您擁有網域管理權

pip install certbot-dns-rfc2136

設定

在提供服務的主機上新增 /etc/letsencrypt/rfc2136.ini 檔案, 檔案權限須為0600, 內容如下

# Target DNS server
dns_rfc2136_server = 10.0.0.1
# Target DNS port
dns_rfc2136_port = 53
# TSIG key name
dns_rfc2136_name = rndckey
# TSIG key secret
dns_rfc2136_secret = mP1z2QD3R156ULti97TbdsRbPBcxe8zoBlaBla
# TSIG key algorithm
dns_rfc2136_algorithm = HMAC-MD5

TSIG Key 是用來更新 named.conf 中區域的字串 , 產生方式如下

dnssec-keygen -a HMAC-SHA512 -b 512 -n HOST rndckey

修改 DNS 管理主機上的 named.conf , 指定需要自動更新的ZONE & 增加控制的TSIG KEY

key rndckey {
                algorithm hmac-md5;
                secret “mP1z2QD3R156ULti97TbdsRbPBcxe8zoBlaBla”;
                };

zone “example.com” {
                type master;
                file “/var/named/example.com.hosts”;
                allow-update {
                                key “rndckey”;
                                };
                };

若考慮安全性可用 update-policy 取代 allow-update, 但需要Bind9以上的版本

測試是否能動態更新DNS

certbot certonly –dry-run –dns-rfc2136 –dns-rfc2136-credentials /etc/letsencrypt/rfc2136.ini –dns-rfc2136-propagation-seconds 30 -d example.com -d *.example.com

若訊息顯示沒有問題就可以以正式取得憑證

certbot certonly –dns-rfc2136 –dns-rfc2136-credentials /etc/letsencrypt/rfc2136.ini –dns-rfc2136-propagation-seconds 30 -d example.com -d *.example.com

若為no-ip 網域因無法使用DNS驗證則測試方式改為(非wildcard憑證)

certbot certonly –dry-run –webroot -w /var/www/html -d yourdomain.no-ip.com

正式取得

certbot certonly –webroot -w /var/www/html -d yourdomain.no-ip.com

申請完成後因為憑證期限為3個月 所以我們需要排成3個約一次執行該指令 另外需要重啟相關使用憑證的服務, 例如:

certbot certonly –dns-rfc2136 –dns-rfc2136-credentials /etc/letsencrypt/rfc2136.ini –dns-rfc2136-propagation-seconds 30 -d example.com -d *.example.com –post-hook ‘systemctl restart httpd;systemctl restart dovecot;systemctl restart sendmail’

如果管理的網域很多也可以直接使用 certbot renew , 但因為certbot版本更新很快, 不是很確定所有狀況 renew 都可以正確更新 , 所以這邊直接使用完整指令更新

參考文獻:

https://certbot-dns-rfc2136.readthedocs.io/en/stable/
https://certbot.eff.org/docs/using.html?highlight=renew
https://evermeet.cx/wiki/Let%27s_Encrypt_with_Apache,_dovecot,_and_sendmail

OpenVPN + PAM + SSSD + Active Directory

OpenVPN伺服器:

系統: Centos8
IP: 10.0.0.10/24

AD驗證伺服器(dc):
Windows 2012 DC (網域功能等級 2003)
網域: mydomain.com
主機FQDN: dc.mydomain.com

憑證伺服器(caserver):
Windows 2003 CA 加密方式SHA1
主機FQDN: caserver.mydomain.com
1. 安裝OpenVPN , 使用路由模式(原生android client不支援 TAP橋接模式)

# 安裝EPEL軟體庫 dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm dnf config-manager --set-enabled PowerTools dnf repolist epel # 安裝 git dnf -y install git cd ~ # 從github下載安裝命令檔 git clone https://github.com/Nyr/openvpn-install.git cd openvpn-install/ chmod +x openvpn-install.sh # 執行安裝檔 ./openvpn-install.sh

接下來依指示輸入你的設定值, 完成後自動產生設定檔 修改 /etc/openvpn/server/server.conf 讓OpenVPN支援PAM

local 10.0.0.10 #主機IP port 1194 proto udp dev tun ca ca.crt cert server.crt key server.key dh dh.pem auth SHA512 tls-crypt tc.key topology subnet server 10.8.0.0 255.255.255.0 ifconfig-pool-persist ipp.txt push "redirect-gateway def1 bypass-dhcp" push "dhcp-option DNS 10.0.0.1" keepalive 10 120 cipher AES-256-CBC user nobody group nobody persist-key persist-tun status openvpn-status.log verb 3 crl-verify crl.pem explicit-exit-notify plugin /usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so login #啟用PAM驗證, 使用預設設定檔/etc/pam.d/login

重新啟動openvpn

systemctl restart openvpn-server@server

修改Client 端的預設值, 由於用戶端要使用與主機不同網段10.1.0.0/24的資源故需要增加路由 /etc/openvpn/server/client-common.txt

client dev tun proto udp remote 1.2.3.4 1194 # 外部實體IP resolv-retry infinite nobind persist-key persist-tun remote-cert-tls server auth SHA512 cipher AES-256-CBC ignore-unknown-option block-outside-dns block-outside-dns auth-user-pass # 除了openvpn本身的金鑰驗證, 另外開啟AD使用者帳號密碼驗證 verb 3 route 10.1.0.0 255.255.255.0 10.0.0.253 # 增加通往10.1.0.0/24網斷路由, 網關為10.0.0.253

更改完成後重新執行安裝命令產生新的client端 .ovpn 設定檔

./openvpn-install.sh

過程中選 Add a new user, 至於第一次產生的user設定可以選擇 Revoke an existing user 移除掉. 產生的 .ovpn 檔會在/root資料夾下 2. 取得網域憑證伺服器的Public key ,通常會在以下位址且檔名類似 \\caserver\CertEnroll\caserver_MYDOMAIN Root Certification Authority.crt 使用cifs工具掛載目錄後 下載到centos8上並轉為PEM格式

# 掛載cifs, server2003使用smb1.0所以參數須加上vers=1.0 mount.cifs //ca_server/CertEnroll /mnt/cifs -o user=administrator,pass=password,dom=mydomain,vers=1.0 cp /mnt/cifs/xxxx.crt xxxx.crt # 將der 轉換為 pem openssl x509 -inform der -in xxxx.crt -out xxxx.pem # 搬移到 trust資料夾 mv xxxx.pem /etc/pki/ca-trust/source/anchors # 將憑證更新至主機信任憑證裡 update-ca-trust

3. 設定sssd 連接 Active Directory 修改/etc/sssd/sssd.conf

[sssd] services = nss, pam, ssh config_file_version = 2 domains = mydomain [sudo] [nss] [pam] offline_credentials_expiration = 60 [domain/mydomain] cache_credentials = True ldap_search_base = dc=mydomain,dc=com id_provider = ldap ldap_uri = ldaps://dc.mydomain.com:636 #AD主機, 使用ssl協定連線 ldap_schema = AD ldap_default_bind_dn = cn=administrator,cn=users,dc= mydomain,dc=com # 這裡為了方便使用管理員帳號, 為安全起見可以使用唯讀的網域帳號 ldap_default_authtok = password_for_administrator # 管理員密碼 ldap_tls_reqcert = demand ldap_tls_cacert = /etc/pki/tls/certs/ca-bundle.crt ldap_tls_cacertdir = /etc/pki/tls/certs ldap_search_timeout = 50 ldap_network_timeout = 60 ldap_id_mapping = True ldap_referrals = false enumerate = False fallback_homedir = /home/%u default_shell = /bin/bash

修改 /etc/openlap/ldap.conf

URI ldaps://dc.mydomain.com:636 base dc=mydomain,dc=com TLS_CACERT /etc/pki/tls/certs/ca-bundle.crt SASL_NOCANON on

強制啟用sssd

authselect select sssd –force systemctl enable --now sssd systemctl restart sssd

由於Windows 2003 CA仍使用舊版SHA1, 因此需要改crypto政策

update-crypto-policies --set LEGACY

完成後重新開機 4. 防火牆上設定允許連向1.2.3.4 UDP1194的流量並引導至內部10.0.0.10 5. 用戶端安裝OpenVPN Client軟體後匯入.ovpn檔 Windows7/8/10 Client: OpenVPN-GUI (嘗試過OpenVPN Connect for Windows無法匯入.ovpn) iOS/Android Client: OpenVPN Connect 參考資料: https://computingforgeeks.com/install-and-configure-openvpn-server-on-rhel-centos-8/ https://www.redhat.com/en/blog/consistent-security-crypto-policies-red-hat-enterprise-linux-8 https://medium.com/jerrynotes/linux-authentication-windows-ad-without-join-domain-7963c3fd44c5

Zoneminder 安裝設定

Zoneminder優點: Web介面, 使用MJPEG格式進行影像判別, 可集中管理多廠牌IP CAM. 使用者幾乎不須安裝任何軟體即可觀看. IP CAM附贈的軟體雖功能多, 但如果在外且有防火牆, 那麼可能受限PORT沒開即無法使用.

缺點: 由於使用MJPEG , 只有影像無聲音, 若開啟動作偵測則耗費CPU效能.

目前網路上有許多大陸海思hisilicon方案號稱960P且支援ONVIF的便宜IP CAM, 索性買了兩個來測試. 雖說號稱960P, 安裝時它的解析度只能到1280×720, 詢問過老闆說確定是130萬畫素, 但怎麼測都無法在ZM及機器原本的操控軟體(yoosee)上達到960P效果 , 看在便宜價格上就算了….
http://goods.ruten.com.tw/item/show?21638660503268

安裝zoneminder

到zoneminder repo下載相對應的rpm package方便安裝
https://zmrepo.zoneminder.com/

因為系統是64bit Centos7

wget http://zmrepo.zoneminder.com/el/7/x86_64/zmrepo-7-7.el7.centos.noarch.rpm
yum install –nogpgcheck zmrepo-7-7.el7.centos.noarch.rpm
yum install zoneminder

由於本身的系統apache使用者非預設的apache帳戶 有權限問題導致無法啟動需要做些修改

chmod -R asterisk:asterisk /var/run/zoneminder /var/log/zoneminder /var/lib/zoneminder

修改 systemd啟動檔 /usr/lib/systemd/system/zoneminder.service

# ZoneMinder systemd unit file for CentOS 7
[Unit]
Description=ZoneMinder CCTV recording and security system
After=network.target mariadb.service httpd.service
Requires=mariadb.service httpd.service
[Service]
User=asterisk # 修改成你的apache啟動user
Type=forking
ExecStart=/usr/bin/zmpkg.pl start
ExecReload=/usr/bin/zmpkg.pl restart
ExecStop=/usr/bin/zmpkg.pl stop
PIDFile=”/var/run/zoneminder/zm.pid”
[Install]
WantedBy=multi-user.target

匯入資料庫schema (這邊使用的是mariadb)

mysql -uroot -p rootpassword < /usr/share/zoneminder/db/zm_create.sql
mysql -uroot -p -e “grant all on zm.* to ‘zmuser’@localhost identified by ‘zmpass’;”
mysqladmin -uroot -p rootpassword reload

zmuser/zmpass為該資料庫的帳號及密碼, rootpassword為資料庫root的密碼

修改/etc/zm/zm.conf 將帳密 及 服務啟動身分 填入

# Username and group that web daemon (httpd/apache) runs as
ZM_WEB_USER=asterisk
ZM_WEB_GROUP=asterisk
# ZoneMinder database user
ZM_DB_USER=zmuser
# ZoneMinder database password
ZM_DB_PASS=zmpass

修改/etc/php.ini的區域時間

[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
;date.timezone =
date.timezone = Asia/Taipei

預設cetos7的apache沒有安裝mod_ssl. ZM會使用系統預設的自簽憑證, 所以要安裝ssl模組

yum install mod_ssl
systemctl restart httpd

修改完即可啟動ZM

systemctl enable zoneminder
systemctl start zoneminder

設定zoneminder

登入https://your.ip/zm
預設沒有帳密所以我們先開啟帳號驗證及更改版面風格

右上options -> system
CSS_DEFAULT 改成flat
LANG_DEFAULT 改成big5_big5
OPT_USE_AUTH 勾選
AUTH_TYPE 選builtin
AUTH_RELY 選hashed
AUTH_HASH_SECRET 填入您用來加密密碼的字串
存檔

options -> display
ZM_CSS 選擇 flat
存檔

重新後登入就會需要帳密了. 預設帳密 admin/admin
如果要修改帳密就到 options -> user
開啟admin帳戶設定填入 新密碼/確認密碼 存檔即可
接下來就是最重要的IP CAM設定 先依手冊將IP CAM設定完成

點選ZM主畫面 -> 新增監視器 -> 一般
名稱: 隨意
來源形式: ffmpeg
功能: Monitor (依需求選擇 這裡只監看)

來源頁籤部分
Source Path: rtsp://admin:your_password_of_ipcam@your_ip:554/onvif1
請填入IP CAM帳密及IP位址, PORT為554, 路徑為onvif1
Remote Method: RTP/Unicast
寬度: 1280
高度: 720

Control頁籤部分
Controllable: 勾選
Control Type: Netcat ONVIF
Control Address: admin:password@your_ip:5000
請填入IP CAM帳密及IP位址, PORT為5000

重複步驟加入所有的IP CAM, 不同廠牌可以到官網Wiki找看看是否有支援
https://wiki.zoneminder.com/
如果你的IP CAM有支援netcatc或ONVIF可以在新增時試試在上方的Probe/ONVIF功能. 由於自己的主機跟IP CAM是在不同網段只能自己新增

完成測試後可以慢慢深入研究去嘗試系統的錄影, 動作偵測錄影(使用電腦主機效能非IP CAM本身硬體偵測), 警報等功能

Samba4 AD DC + DHCPD + BIND (Dynamic DNS)

Samba 4 已經釋出很長一段時間了 因此趁著升級電腦與 centos 6 順便將 Samba 3 AD DC + dhcpd + bind 更新為 Samba 4 + bind 9 dlz 模組 + dhcpd

DC DQDN名稱 : samba4dc

DC IP : 192.168.0.1/24

  1. 首先到 https://portal.enterprisesamba.com/users/sign_up 註冊. 方便使用 yum 升級 samba , 如果使用 source 安裝就不需申請. 登入後把給 centos6 用的 sernet-samba-4.1.repo 檔下載回來並修改檔案中 USERNAME:ACCESSKEY 的部分.
  2. 升級前先備份 /etc/samba, /var/lib/samba, /etc/dhcp, /etc/named.conf, /var/named, /var/cache/samba 等目錄
  3. 安裝 samba 4
    # yum install sernet-samba -y
  4. 升級 Samba AD 網域
    移動設定檔

    mv /etc/smb.conf /etc/smb.PDC.conf

    將舊資料庫等檔案移到其他位置

    # mv /var/lib/samba/ /var/lib/samba.PDC/
    # mv /var/cache/samba/ /var/cache/samba.PDC/

    新增資料夾. 並將升級時會用到的資料庫檔案複製到該目錄

    # mkdir /var/lib/samba.PDC/dbdir/
    # cp -p /var/lib/samba.PDC/private/secrets.tdb /var/lib/samba.PDC/dbdir/
    # cp -p /var/lib/samba.PDC/private/schannel_store.tdb /var/lib/samba.PDC/dbdir/
    # cp -p /var/lib/samba.PDC/private/passdb.tdb /var/lib/samba.PDC/dbdir/
    # cp -p /var/cache/samba.PDC/gencache_notrans.tdb /var/lib/samba.PDC/dbdir/
    # cp -p /var/cache/samba.PDC/group_mapping.tdb /var/lib/samba.PDC/dbdir/
    # cp -p /var/cache/samba.PDC/account_policy.tdb /var/lib/samba.PDC/dbdir/

    升級資料庫以及使用 bind_dlz 模組

    # samba-tool domain classicupgrade --dbdir=/var/lib/samba.PDC/dbdir/ --use-xattrs=yes --realm=home.com --dns-backend=BIND9_DLZ /etc/smb.PDC.conf --option="interfaces=lo eth0" --option="bind interfaces only=yes"
    PS: --option="interfaces=lo eth0" --option="bind interfaces only=yes" 這是限定 samba 只作用在網卡 loopback 及 eth0
  5. 調整產生的 samba 設定即啟動檔
    /etc/samba/smb.conf

    [global]
            workgroup = HOME
            realm = home.com
            netbios name = SAMBA4DC
            interfaces = lo, eth0
            bind interfaces only = Yes
            server role = active directory domain controller
            server services = s3fs, rpc, nbt, wrepl, ldap, cldap, kdc, drepl, winbind, ntp_signd, kcc, dnsupdate
            idmap_ldb:use rfc2307 = yes
            log level = 2
            log file = /var/log/samba/log.%m
            max log size = 50
            wins support = yes
            syslog = 0
            username map = /etc/samba/smbusers
            domain master = yes
            domain logons = yes
            local master = yes
            preferred master = yes
    
    [netlogon]
            path = /var/lib/samba/sysvol/home.com/scripts
            read only = No
    
    [sysvol]
            path = /var/lib/samba/sysvol
            read only = No
    
    [homes]
            comment = Home Directories
            browseable = no
            read only = No
            valid users = %S
            create mask = 0700
            directory mask = 0700
    
    [nas]
            comment = storage
            path = /home/data
            public = yes
            writable = yes
            printable = no
            write list = +adm

    因為是作為 dc , 只要開啟 sernet-samba-ad 服務. 其餘 sernet-samba-nmbd, sernet-samba-smbd, sernet-samba-winbindd 不須啟動.

    # chkconfig --level 2345 sernet-samba-ad on
  6. 調整 bind9 & kerberos 設定
    /etc/named.conf

    options {
            listen-on port 53 { 127.0.0.1; };
            listen-on-v6 port 53 { ::1; };
            directory       "/var/named";
            dump-file       "/var/named/data/cache_dump.db";
            statistics-file "/var/named/data/named_stats.txt";
            memstatistics-file "/var/named/data/named_mem_stats.txt";
    
            forwarders {
                    168.95.1.1;
                    };
            forward first;
            listen-on {
                    home;
            };
            allow-recursion {home;};
            allow-update { home; };
            allow-query { home; };
            allow-transfer { home;};
            listen-on-v6 { none; };
            tkey-gssapi-keytab "/var/lib/samba/private/dns.keytab"; #加入這行
            auth-nxdomain yes;
            empty-zones-enable no;
            version none;
            hostname none;
            server-id none;
    };
    
    logging {
            channel Named_log {
                file "data/named.run";# versions 5 size 5m;
                severity dynamic;
                print-severity  yes;
                print-time yes; };
            category default {Named_log; };
            category xfer-out {Named_log; };
            category queries {Named_log; };
    };
    
    acl "home" { 192.168.0.0/24; 127.0.0.1;};
    
    controls {
            inet 127.0.0.1 allow { localhost; } keys { rndc-key; };
    };
    
    zone "." IN {
            type hint;
            file "named.ca";
    };
    
    include "/etc/named.rfc1912.zones";
    include "/etc/named.root.key";
    include "/etc/rndc.key";
    include "/var/lib/samba/private/named.conf";   #加入這行

    /var/lib/samba/private/named.conf

    lz "AD DNS Zone" {
        # For BIND 9.8.0
        database "dlopen /usr/lib64/samba/bind9/dlz_bind9.so"; #選擇對應的 bind 版本
    
        # For BIND 9.9.0
        # database "dlopen /usr/lib64/samba/bind9/dlz_bind9_9.so";
    };

    修改 keytab 檔案權限讓 bind 可以用其來動態更新 zone

    # chgrp named /var/lib/samba/private
    # chgrp named /var/lib/samba/private/dns.keytab
    # chmod g+r /var/lib/samba/private/dns.keytab

    連結 kerberos 設定檔到 /etc 下

    # ln -sf /var/lib/samba/private/krb5.conf /etc/krb5.conf

    重啟 named

    # service named restart

    增加反解析區域

    # samba-tool dns zonecreate samba4dc.home.com 0.168.192.in-addr.arpa

    將 DC 的 PTR 加入反解區域

    # samba-tool dns add samba4dc.home.com 0.168.192.in-addr.arpa 1 PTR samba4dc.home.com

    如果有設定 ntpd (選擇性) 請修改 socket 的位址讓 samba 可以讀取

    driftfile /var/lib/ntp/drift
    logfile         /var/log/ntp
    ntpsigndsocket  /var/lib/samba/ntp_signd
    
    restrict default kod nomodify notrap nopeer mssntp noquery
    restrict -6 default kod nomodify notrap nopeer noquery
    
    restrict 127.0.0.1
    restrict -6 ::1
    
    restrict 192.168.0.0 mask 255.255.255.0 nomodify notrap
    
    server 0.centos.pool.ntp.org iburst
    server 1.centos.pool.ntp.org iburst
    server 2.centos.pool.ntp.org iburst
    server 3.centos.pool.ntp.org iburst
    
    includefile /etc/ntp/crypto/pw
    
    keys /etc/ntp/keys

    修改權限及重啟 ntpd

    # chown root:ntp /var/lib/samba/ntp_signd
    # chmod 750 /var/lib/samba/ntp_signd
    # service ntpd restart

    重啟 samba

    # service smbd stop
    # service nmbd stop
    # service sernet-samba-ad start
  7. DHCPD 設定
    在 AD 裡新增 dhcp 這個使用者並給予權限讓它可以動態更新 DNS(也可以使用 Windows 遠端伺服器管理工具 RSAT 來新增)

    # samba-tool user create dhcp --description="Unprivileged user for DNS updates via DHCP server"
    # samba-tool group addmembers DnsAdmins dhcp

    將該使用者憑證匯出成 keytab 檔

    # cd /etc/dhcp
    # samba-tool domain exportkeytab --principal=dhcp@HOME.COM dhcpd.keytab
    # chown root:dhcpd /etc/dhcp/dhcpd.keytab
    # chmod 440 /etc/dhcp/dhcpd.keytab
    # chgrp dhcpd /etc/dhcp

    新增以下兩個執行檔
    /usr/local/sbin/dhcp-dyndns.sh

    #!/bin/bash
    $(dirname $0)/dns-krbnsupdate.sh $@ 2>&1 | logger &

    /usr/local/sbin/dns-krbnsupdate.sh

    #!/bin/bash
    
    # This script is for secure DDNS updates using GSS/TSIG
    # Version: 0.1
    
    ## CONFIGURATION ##
    # Kerberos realm
    realm="HOME.COM"
    # Kerberos principal
    principal="dhcp@$realm"
    # Kerberos keytab
    keytab="/etc/dhcp/dhcpd.keytab"
    # Kerberos credentials cache
    krb5cc="/tmp/krb5cc_0"
    # Use MIT kerberos args instead of heimdal.
    KRB5MIT="YES"
    
    # Domain appended to hostname
    domain="home.com"
    # Space separated list of DNS servers for sending updates to
    NSRVS="cchisheng.home.com"
    # Default DNS resource records TTL
    RRTTL="3600"
    # Do not use TXT RRs (rfc4701)
    NOTXTRRS="YES"
    
    # Additional nsupdate flags (-g already applied), e.g. "-d" for debug
    #NSUPDFLAGS="-d"
    # Run in the foreground (for manual run only!!!), it's better to use "-d" as script's first argument
    #DEBUG="YES"
    
    ######################################################
    
    ## VARIABLES ##
    [ "$1" = "-d" ] && DEBUG="YES" && shift
    action=$1
    ip=$2
    DHCID=$3
    name=${4%%.*}
    [ -n "$5" ] && RRTTL="$5"
    
    _usage() {
    echo "Usage:"
    echo " `basename $0` [-d] add ip-address dhcid|mac-address hostname [dns-ttl]"
    echo " `basename $0` [-d] delete ip-address dhcid|mac-address"
    }
    
    _kerberos() {
    export KRB5_KTNAME="$keytab"
    export KRB5CCNAME="$krb5cc"
    
    if [ "$KRB5MIT" = "YES" ]; then
     KLISTARG="-s"
    else
     KLISTARG="-t"
    fi
    
    klist $KLISTARG || kinit -k -t "$keytab" -c "$krb5cc" "$principal" || { echo "DDNS: kinit failed"; exit 1; }
    }
    
    _main() {
    umask 77
    
    if [ -z "$ip" ] || [ -z "$DHCID" ]; then
     _usage
     exit 1
    fi
    
    
    ## NSUPDATE ##
    case "$action" in
     add)
     RRPTR="$name.$domain"
     if [ "$NOTXTRRS" != "YES" ]; then
     NOTXTRRS=""
     RRAOLD=`host $RRPTR | awk '/has address/ {print $4}'`
     if [ -n "$RRAOLD" ]; then
     RRTXTOLD=`host -t txt "$RRPTR" | sed -n '/descriptive text/s/^.*[[:space:]]descriptive text[[:space:]]*"\(.*\)"$/\1/p'`
     [ -z "$RRTXTOLD" ] && echo "DDNS: adding records for $ip ($RRPTR) FAILED: has A record but no DHCID, not mine" && exit 1
    
     RRTXT=`echo "$DHCID$RRPTR" | sha256sum`
     RRTXT="000101${RRTXT%% *}"
     [ "$RRTXT" != "$RRTXTOLD" ] && echo "DDNS: adding records for $ip ($RRPTR) FAILED: has A record but DHCID is wrong" && exit 1
     else
     RRTXT=`echo "$DHCID$RRPTR" | sha256sum`
     RRTXT="000101${RRTXT%% *}"
     fi
     else
     NOTXTRRS=";"
     fi
    
     RRPTRNAME=`echo $ip | awk -F '.' '{print $4"."$3"."$2"."$1".in-addr.arpa"}'`
    
     _kerberos
    
     for NSRV in $NSRVS; do
     nsupdate -g $NSUPDFLAGS << UPDATE
    server $NSRV
    realm $realm
    update delete $RRPTR. $RRTTL A
    ${NOTXTRRS}update delete $RRPTR. $RRTTL TXT
    ${NOTXTRRS}update add $RRPTR. $RRTTL TXT $RRTXT
    update add $RRPTR. $RRTTL A $ip
    send
    update delete $RRPTRNAME. $RRTTL PTR
    update add $RRPTRNAME. $RRTTL PTR $name.$domain.
    send
    UPDATE
      result=$?
     [ "$result" -eq "0" ] && echo "DDNS: adding records for $ip ($RRPTR) succeeded" && exit 0
     done
    
     [ "$result" != "0" ] && echo "DDNS: adding records for $ip ($RRPTR) FAILED: nsupdate status $result" && exit "$result"
     ;;
     delete)
     RRPTR=`host $ip | awk '/domain name pointer/ { sub(/\.$/, "", $5); print $5}'`
     if [ "$NOTXTRRS" != "YES" ]; then
     NOTXTRRS=""
     if [ -n "$RRPTR" ]; then
     RRTXTOLD=`host -t txt "$RRPTR" | sed -n '/descriptive text/s/^.*[[:space:]]descriptive text[[:space:]]*"\(.*\)"$/\1/p'`
     [ -z "$RRTXTOLD" ] && echo "DDNS: removing records for $ip ($RRPTR) FAILED: has A record but no DHCID, not mine" && exit 1
    
     RRTXT=`echo "$DHCID$RRPTR" | sha256sum`
     RRTXT="000101${RRTXT%% *}"
     [ "$RRTXT" != "$RRTXTOLD" ] && echo "DDNS: removing records for $ip ($RRPTR) FAILED: has A record but DHCID is wrong" && exit 1
     else
     echo "DDNS: removing records for $ip FAILED: has no PTR, can not determine A record" && exit 1
     fi
     else
     NOTXTRRS=";"
     fi
    
     RRPTRNAME=`echo $ip | awk -F '.' '{print $4"."$3"."$2"."$1".in-addr.arpa"}'`
    
     _kerberos
    
     for NSRV in $NSRVS; do
     nsupdate -g $NSUPDFLAGS << UPDATE
    server $NSRV
    realm $realm
    update delete $RRPTR. $RRTTL A
    ${NOTXTRRS}update delete $RRPTR. $RRTTL TXT
    send
    update delete $RRPTRNAME. $RRTTL PTR
    send
    UPDATE
     result=$?
     [ "$result" -eq "0" ] && echo "DDNS: removing records for $ip ($RRPTR) succeeded" && exit 0
     done
    
     [ "$result" != "0" ] && echo "DDNS: removing records for $ip ($RRPTR) FAILED: nsupdate status $result" && exit "$result"
     ;;
     *)
     _usage && exit 1
     ;;
    esac
    }
    
    if [ "$DEBUG" = "YES" ]; then
     _main
    else
     :
     _main | logger -s -t dhcpd &
    fi

    修改 /etc/dhcp/dhcpd.conf

    subnet 192.168.0.0 netmask 255.255.255.0 {
     authoritative;
     option netbios-name-servers 192.168.0.1;
     option domain-name-servers 192.168.0.1;
     option domain-name "home.com";
     option netbios-node-type 8;
     option routers 192.168.1.1;
     option subnet-mask 255.255.255.0;
     default-lease-time 259200;
     range 192.168.0.10 192.168.1.250;
     on commit {
     set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
     set ClientName = pick-first-value(option host-name, host-decl-name);
     set ClientDHCID = binary-to-ascii(16, 8, ":", hardware);
     execute("/usr/local/sbin/dhcp-dyndns.sh", "add", ClientIP, ClientDHCID, ClientName);
     }
     on release {
     set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
     set ClientName = pick-first-value(option host-name, host-decl-name);
     set ClientDHCID = binary-to-ascii(16, 8, ":", hardware);
     execute("/usr/local/sbin/dhcp-dyndns.sh", "delete", ClientIP, ClientDHCID);
     }
     on expiry {
     set ClientIP = binary-to-ascii(10, 8, ".", leased-address);
     set ClientName = pick-first-value(option host-name, host-decl-name);
     set ClientDHCID = binary-to-ascii(16, 8, ":", hardware);
     execute("/usr/local/sbin/dhcp-dyndns.sh", "delete", ClientIP, ClientDHCID);
     }
    }

    改變檔案權限

    # chmod 755 /usr/local/sbin/dhcp-dyndns.sh
    # chmod 755 /usr/local/sbin/dns-krbnsupdate.sh

    重啟 dhcpd

    # service dhcpd restart
  8. 測試
    # samba_dnsupdate --verbose --all-names

    若上述指令沒有錯誤表示 bind9 設定正確. 若有錯誤請檢查檔案及目錄權限, 讓 bind9 可以讀取  dns.keytab
    當 dhcp client 端開機或者在 Windows 命令提示視窗執行 ipconfig /renew 時, server上的 syslog 會有以下紀錄, 表示動態更新成功

    Dec  9 00:00:15 samba4dc dhcpd: DDNS: adding records for 192.168.0.186 (win7.home.com) succeeded
    Dec  9 00:00:15 samba4dc logger: dhcpd: DDNS: adding records for 192.168.0.186 (win7.home.com) succeeded
  9. 問題
    I.Windows client本身會執行 secure dns update, 因此 named 紀錄裡會有更新失敗的錯誤. 由於我們是透過dhcpd更新dns, 因此該錯誤可以忽略.
    II.Samba4目前對於讓 dc 及file server 在同台伺服器上尚未完整支援, 因此 client 端在網路芳鄰內找不到 server, 需要手動輸入 \\server 連結伺服器. 如果在登入指令檔或者 RSAT 的使用者管理裡指定連線磁碟機就可以解決該問題
    III. RSAT 的 DNS 管理員可以新增刪除紀錄但有時會有錯誤訊息但不影響
  10. 參考文獻
    https://wiki.samba.org/index.php/User_Documentation
    http://blog.michael.kuron-germany.de/2011/02/isc-dhcpd-dynamic-dns-updates-against-secure-microsoft-dns/
    https://wiki.archlinux.org/index.php/Samba_4_Active_Directory_Domain_Controller

SASL + PAM 無法紀錄 rhost 以配合 fail2ban 的解法

如果cnetos5系統使用 saslauthd + PAM + sendmail 時, 當遠端使用 sasl 認證發生錯誤時相關紀錄檔並不會紀錄遠端的 ip 位址

/var/log/messages

Jan 26 07:14:12 fedora saslauthd[27264]: do_auth         : auth failure: [user=user1] [service=smtp] [realm=] [mech=pam] [reason=PAM auth error]
Jan 26 07:14:18 fedora saslauthd[27267]: do_auth         : auth failure: [user=user1] [service=smtp] [realm=] [mech=pam] [reason=PAM auth error]
Jan 26 07:14:22 fedora saslauthd[27262]: do_auth         : auth failure: [user=user1] [service=smtp] [realm=] [mech=pam] [reason=PAM auth error]
Jan 26 07:14:26 fedora saslauthd[27265]: do_auth         : auth failure: [user=user1] [service=smtp] [realm=] [mech=pam] [reason=PAM auth error]
Jan 26 07:14:32 fedora saslauthd[27267]: do_auth         : auth failure: [user=user1] [service=smtp] [realm=] [mech=pam] [reason=PAM auth error]

/var/log/maillog

Jan 26 07:14:13 fedora sendmail[29536]: s0PNE8Zh029536: [78.93.245.133] did not issue MAIL/EXPN/VRFY/ETRN during connection to MTA
Jan 26 07:14:18 fedora sendmail[29537]: s0PNED8R029537: [78.93.245.133] did not issue MAIL/EXPN/VRFY/ETRN during connection to MTA
Jan 26 07:14:23 fedora sendmail[29538]: s0PNEItR029538: [78.93.245.133] did not issue MAIL/EXPN/VRFY/ETRN during connection to MTA
Jan 26 07:14:28 fedora sendmail[29539]: s0PNENjN029539: [78.93.245.133] did not issue MAIL/EXPN/VRFY/ETRN during connection to MTA
Jan 26 07:14:32 fedora sendmail[29540]: s0PNESYI029540: [78.93.245.133] did not issue MAIL/EXPN/VRFY/ETRN during connection to MTA

/var/log/secure

Jan 26 07:14:10 fedora saslauthd[27264]: pam_unix(smtp:auth): check pass; user unknown
Jan 26 07:14:10 fedora saslauthd[27264]: pam_unix(smtp:auth): authentication failure; logname= uid=0 euid=0 tty= ruser= rhost=
Jan 26 07:14:10 fedora saslauthd[27264]: pam_succeed_if(smtp:auth): error retrieving information about user chi
Jan 26 07:14:15 fedora saslauthd[27267]: pam_unix(smtp:auth): check pass; user unknown
Jan 26 07:14:15 fedora saslauthd[27267]: pam_unix(smtp:auth): authentication failure; logname= uid=0 euid=0 tty= ruser= rhost=
Jan 26 07:14:15 fedora saslauthd[27267]: pam_succeed_if(smtp:auth): error retrieving information about user chi
Jan 26 07:14:21 fedora saslauthd[27262]: pam_unix(smtp:auth): check pass; user unknown
Jan 26 07:14:21 fedora saslauthd[27262]: pam_unix(smtp:auth): authentication failure; logname= uid=0 euid=0 tty= ruser= rhost=
Jan 26 07:14:21 fedora saslauthd[27262]: pam_succeed_if(smtp:auth): error retrieving information about user chi
Jan 26 07:14:25 fedora saslauthd[27265]: pam_unix(smtp:auth): check pass; user unknown
Jan 26 07:14:25 fedora saslauthd[27265]: pam_unix(smtp:auth): authentication failure; logname= uid=0 euid=0 tty= ruser= rhost=
Jan 26 07:14:25 fedora saslauthd[27265]: pam_succeed_if(smtp:auth): error retrieving information about user chi
Jan 26 07:14:30 fedora saslauthd[27267]: pam_unix(smtp:auth): check pass; user unknown
Jan 26 07:14:30 fedora saslauthd[27267]: pam_unix(smtp:auth): authentication failure; logname= uid=0 euid=0 tty= ruser= rhost=
Jan 26 07:14:30 fedora saslauthd[27267]: pam_succeed_if(smtp:auth): error retrieving information about user chi

主要原因是因為 cyrus-sasl 當初設計只紀錄四個欄位不包含遠端 ip , 網路上有 patch 可以增加 rhost 欄 , 但是因為它會影響其他軟體目前並未被納入正式的 package. 相關資訊可以參考以下討論串
https://bugzilla.cyrusimap.org/show_bug.cgi?id=3468
https://bugzilla.redhat.com/show_bug.cgi?id=683797

rhost 為空值的話 fail2ban 就無法阻擋 smtp-auth 密碼猜測的攻擊. 測試版的 fail2ban 0.9 增加了一樣令人興奮的功能 , 可以在過濾器裡進行多行比對!!如此一來只要增加 sendmail 的 log level (預設為 9) , 就可以看出遠端 ip 及認證錯誤的關聯性再利用 fail2ban 加以阻擋.

首先修改 sendmail.mc 檔, 變更以下行

dnl define(`confLOG_LEVEL’, `9′)dnl

改為

define(`confLOG_LEVEL’, `10‘)dnl

執行指令後並重新啟動 sendmail

[root@mailhost /]# m4 /etc/mail/senmail.mc > /etc/mail/sendmail.cf
[root@mailhost /]# service sendmail restart

此時檢視 /var/log/maillog 會發現 sasl 認證錯誤時訊息如下

Jan 26 19:30:01 fedora sendmail[2370]: NOQUEUE: connect from 223.59.18.218.broad.sz.gd.dynamic.163data.com.cn [218.18.59.223] (may be forged)
Jan 26 19:30:05 fedora sendmail[2370]: s0QBU1Ir002370: AUTH failure (LOGIN): authentication failure (-13) SASL(-13): authentication failure: checkpass failed
Jan 26 19:30:06 fedora sendmail[2370]: s0QBU1Ir002370: 223.59.18.218.broad.sz.gd.dynamic.163data.com.cn [218.18.59.223] (may be forged) did not issue MAIL/EXPN/VRFY/ETRN during connection to MTA

這時紀錄了 pid 及 mail ID 及驗證錯誤相關訊息 . 原來的 Log Level 只會紀錄最後一行, 但是該行錯誤在某些為了快速發信的軟體或者電子報等的不嚴謹的軟體連接伺服器時都可能發生, 因此光靠該行無法明確判斷是否為垃圾郵件. 現在在本例中我們可以確認它是在使用PLAIN TEXT驗證後才發生該錯誤 . 注意在繁忙的 server 中 ,該錯誤並不一定會連在一起, 因為server同時會處理其他服務如dovecot , 所以我們該使用 pid 或者 mail ID 來關聯這些錯誤.

接下來就是在 fail2ban 的 git 下載 0.9 版並安裝(略)
https://github.com/fail2ban/fail2ban/tarball/0.9

0.9版設定上有些差異 , 說明有提到盡量將各別設定或者自訂部份放在 /etc/fail2ban/jail.local 或者 /etc/fail2ban/jail.d 下

/etc/fail2ban/fail2ban.conf

[Definition]
loglevel = 3
logtarget = /var/log/fail2ban.log #個人比較喜歡紀錄在個別檔案中(預設值 SYSLOG)
socket = /var/run/fail2ban/fail2ban.sock
pidfile = /var/run/fail2ban/fail2ban.pid

/etc/fail2ban/jail.conf  這邊只列一些預設項目和重要設定, logpath部份注意一下, 當然也可以在jail.d下面覆蓋預設值.其他要新增的設定我們會加到/etc/fail2ban/jail.d/local.conf

[DEFAULT]
ignoreip = 127.0.0.1/8 10.0.18.0/24 10.160.8.0/23 #內部 ip 不阻擋
ignorecommand =
bantime  = 1200 #擋20分鐘
findtime  = 600
maxretry = 5 #出現五次紀錄即觸發
backend = auto
usedns = warn
logencoding = auto
enabled = false #預設不啟用任何服務 要啟用各別服務請在 jail.d下設定
filter = %(__name__)s
destemail = root@localhost
sender = root@localhost
mta = sendmail
protocol = tcp
chain = INPUT
port = 0:65535
banaction = iptables-multiport
action_ = %(banaction)s[name=%(__name__)s, port=”%(port)s”, protocol=”%(protocol)s”, chain=”%(chain)s”]
action_mw = %(banaction)s[name=%(__name__)s, port=”%(port)s”, protocol=”%(protocol)s”, chain=”%(chain)s”]
%(mta)s-whois[name=%(__name__)s, dest=”%(destemail)s”, protocol=”%(protocol)s”, chain=”%(chain)s”]
action_mwl = %(banaction)s[name=%(__name__)s, port=”%(port)s”, protocol=”%(protocol)s”, chain=”%(chain)s”]
%(mta)s-whois-lines[name=%(__name__)s, dest=”%(destemail)s”, logpath=%(logpath)s, chain=”%(chain)s”]
action_xarf = %(banaction)s[name=%(__name__)s, port=”%(port)s”, protocol=”%(protocol)s”, chain=”%(chain)s”]
xarf-login-attack[service=%(__name__)s, sender=”%(sender)s”, logpath=%(logpath)s, port=”%(port)s”]
action_blocklist_de  = blocklist_de[email=”%(sender)s”, service=%(filter)s, apikey=”%(blocklist_de_apikey)s”]
action = %(action_)s
[sshd]
port    = ssh
logpath = /var/log/secure
[sshd-ddos]
port    = ssh
logpath = /var/log/secure
[dovecot]
port    = pop3,pop3s,imap,imaps,submission,465,sieve
logpath = /var/log/maillog
[dovecot-auth]
filter  = dovecot
port    = pop3,pop3s,imap,imaps,submission,465,sieve
logpath = /var/log/secure

新增我們的過濾規則 /etc/fail2ban/filter.d/sendmail-sasl.conf

[Definition]
#比對規則 msgid 為多行比對中的關聯值 也就是mail ID
failregex = sendmail.*: (?P<msgid>[^:]+): AUTH failure.*\n(?:.*\n)*?.+ sendmail.*: (?P=msgid): .*\[<HOST>\] .*to MTA
ignoreregex =
[Init]
#設定LOG一次讀取到buffer的行數, 如果sever很忙碌導致符合的行中間插入很多其它的log , 你可以增加buffer行數值
maxlines = 10

啟用我們要檢查的服務 /etc/fail2ban/jail.d/local.conf

[DEFAULT]
[sshd]
enabled  = true
filter   = sshd
action   = iptables-allports[name=FTP, port=ftp, protocol=tcp]
logpath  = /var/log/secure
[vsftpd]
enabled  = true
filter   = vsftpd
action   = iptables-allports[name=FTP, port=ftp, protocol=tcp]
logpath  = /var/log/secure
[sendmail]
enabled  = true
filter   = sendmail
action   = iptables-allports[name=SENDMAIL, port=smtp, protocol=tcp]
logpath  = /var/log/maillog
[dovecot]
enabled  = true
filter   = dovecot
action   = iptables-allports[name=DOVECOT, port=”pop3,pop3s,imap,imaps”, protocol=tcp]
logpath  = /var/log/maillog
[dovecot-auth]
enabled  = true
filter  = dovecot
action   = iptables-allports[name=DOVECOT, port=”pop3,pop3s,imap,imaps”, protocol=tcp]
logpath = /var/log/secure
[sendmail-sasl]
enabled  = true
filter   = sendmail-sasl
action   = iptables-allports[name=SENDMAIL, port=smtp, protocol=tcp]
logpath  = /var/log/maillog

開始測試過濾規則 , 由於繁忙的server maillog 相當大 , 建議先複製小部份到測試用的檔案

[root@mailhost /]# fail2ban-regex /tmp/test.log .conf /etc/fail2ban/filter.d/sendmail-sasl.conf

若有符合的結果則顯示如下

Running tests
=============
Use   failregex file : sendmail-sasl.conf
Use         maxlines : 10
Use         log file : test.log
Use         encoding : UTF-8
Results
=======
Failregex: 21 total
|-  #) [# of hits] regular expression
|   1) [21] sendmail.*: (?P<msgid>[^:]+): AUTH failure.*\n(?:.*\n)*?.+ sendmail.*: (?P=msgid): .*\[<HOST>\] .*to MTA
`-
Ignoreregex: 0 total
Date template hits:
|- [# of hits] date format
|  [102] MON Day 24hour:Minute:Second
`-
Lines: 102 lines, 0 ignored, 42 matched, 60 missed
Missed line(s):: too many to print.  Use –print-all-missed to print all 60 lines

最後啟動 fail2ban 服務

[root@mailhost /]# service fail2ban start

接下來就是觀察/var/log/fail2ban.log , 看看是否有 BAN 掉惡意的 ip 來源囉

使用Squid 3.2 建立Fully Transparent Proxy(TPROXY4.1+)

環境中有使用NLTM驗證 + IIS7.5的應用服務並且會檢查Client端IP位址. 原來的transparent proxy無法通過檢查, 需改成TPROXYv4.1+ (Fully Transparent Proxy), 如此一來伺服器看到Client的IP才不會是Proxy Server的IP.

安裝過程發現Squid 3.2.0的ntlm支援有問題, IE會不段重複跳出要求使用者輸入帳號密碼, 查了論壇發現該版本有bug, 改成3.2.7就解決了.

 

系統:Centos 6.4

軟體:squid-3.2.7,bridge-utils,ebtables,libcap,libecap. Squid網路上都有包好的rpm檔,下載回來裝即可.若自行編譯核心或想自行編譯squid者請參考http://wiki.squid-cache.org/Features/Tproxy4. 其他package使用yum安裝.

網路架構:IPv4,主機為bridge模式接在gateway後

軟體設定

  1. 將主機設定為Bridge.記得先關閉NetworkManager以免設定衝突
    建立 /etc/sysconfig/network-scripts/ifcfg-br0 內容如下

    DEVICE=”br0″
    NM_CONTROLLED=”no”
    TYPE=”Bridge”
    BOOTPROTO=”none”
    IPADDR=”10.0.0.2″
    NETMASK=”255.255.255.0″
    BROADCAST=”10.0.0.255″
    NETWORK=”10.0.0.0″
    ONBOOT=”yes”
    GATEWAY=”10.0.0.1″
    DNS1=10.0.0.3
    DNS2=10.0.0.4
    DOMAIN=mydomain.com

    外部網卡 /etc/sysconfig/network-scripts/ifcfg-eth0 內容如下

    DEVICE=”eth0″
    NM_CONTROLLED=”no”
    ONBOOT=”yes”
    TYPE=”Ethernet”
    BRIDGE=”br0″

    內部網卡 /etc/sysconfig/network-scripts/ifcfg-eth1 內容如下

    DEVICE=”eth1″
    NM_CONTROLLED=”no”
    ONBOOT=”yes”
    TYPE=”Ethernet”
    BRIDGE=”br0″

    設定完成後重新開機或重起network服務.
  2. 確認 /etc/sysctl.conf的相關設定包含下面幾行

    net.ipv4.ip_forward = 1
    net.bridge.bridge-nf-call-ip6tables = 01
    net.bridge.bridge-nf-call-iptables = 01
    net.bridge.bridge-nf-call-arptables = 01
    net.ipv4.conf.default.rp_filter = 01
    net.ipv4.conf.all.rp_filter = 01
    net.ipv4.conf.eth0.rp_filter = 01
    net.ipv4.conf.eth1.rp_filter = 01

    執行以下指令使設定生效

    [root@centos6 etc]# sysctl –p

  3. 設定iptables及ebtables規則

    建立執行檔 /usr/local/bin/tproxy.init

    #!/bin/bash
    # IPv4-only
    # 在lo介面上建立代號為100的路由表格給iptables比對fwmark
    ip -f inet rule add fwmark 1 lookup 100
    ip -f inet route add local default dev lo table 100
    # 以下是不需要進入squid的例外規則, 例如本機有提供web服務
    iptables -t mangle -A PREROUTING -d 127.0.0.1 -p tcp –dport 80 -j ACCEPT
    #加入Divert規則將TCP80埠的流量重導到TCP3129
    iptables -t mangle -N DIVERT
    iptables -t mangle -A DIVERT -j MARK –set-mark 1
    iptables -t mangle -A DIVERT -j ACCEPT
    iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
    iptables -t mangle -A PREROUTING -p tcp –dport 80 -j TPROXY –tproxy-mark 0x1/0x1 –on-port 3129
    # 將橋接模式的封包移到路由模式
    ebtables -t broute -A BROUTING -i eth1 -p ipv4 –ip-proto tcp –ip-dport 80 -j redirect –redirect-target DROP
    ebtables -t broute -A BROUTING -i eth0 -p ipv4 –ip-proto tcp –ip-sport 80 -j redirect –redirect-target DROP

    賦予執行權限

    [root@centos6 bin]# chmod 755 tproxy.init

    將上面檔案加入開機程序 /etc/rc.d/rc.local

    #!/bin/sh
    #
    # This script will be executed *after* all the other init scripts.
    # You can put your own initialization stuff in here if you don’t
    # want to do the full Sys V style init stuff.
    touch /var/lock/subsys/local
    /usr/local/bin/tproxy.init

  4. 修改squid設定檔 /etc/squid/squid.conf .確認下面2行存在

    #限定IPv4, 避免LOG有錯誤訊息
    http_port 0.0.0.0:3128
    http_port 0.0.0.0:3129 tproxy

    重起squid服務.

  5. 雖然主機為橋接模式, 但為了讓Squid服務可以運作所以仍需給予伺服IP及相關路由, DNS以存取Web. 另外若使用selinux則另需以下設定:

    setsebool squid_connect_any=yes
    setsebool squid_use_tproxy=yes

  6. 檢查 /var/log/squid/access.log 若有client的瀏覽紀錄表示squid開始運作.

MailWatch 1.1.5.1 UTF-8 中文化版本

MailWatch 1.1.5.1 UTF-8 中文化版本
介面部分使用gettext國際化, 繁體中文部份大致翻譯完成
UTF-8主旨及郵件都可正確顯示,解壓縮覆蓋原來的mailscanner目錄即可
若使用舊的 conf.php 裏要增加下面這行將介面切換至繁體
define(‘SYSTEM_LOCALE’,’zh_TW’);
簡體漢化 (直接 iconv 轉換 po 檔)
define(‘SYSTEM_LOCALE’,’zh_CN’);
若要讓MailWatch報表裏的jpgraph圖形正確顯示中文則另外要設定字型
# cp /usr/path_to_truetype_font/ukai.ttf /path_to_mailwatch/jpgraph/src/fonts/ukai.ttf
# ln -s /path_to_mailwatch/jpgraph/src/fonts/ukai.ttf /path_to_mailwatch/jpgraph/src/fonts/bkai00mp.ttf

MailWatch 1.1.5.1 UTF-8 中文化版本

mailwatch 與 php 5.3

將Centos5的php5.1升級到5.3後mailwatch 1.04的log會出現:
Deprecated: Function ereg_replace() is deprecated in /var/www/html/mailscanner/functions.php on line 936
5.3版的php不建議繼續使用ereg_replace()函數, 可以改用preg_replace(). 改完後log還是有些其他錯誤. 拜完google後搜尋到mailwatch的mailing list這篇完整的教學
http://permalink.gmane.org/gmane.mail.virus.mailscanner.mailwatch.general/8861

按說明將所有pear模組及jpgraph升級到最新版本, 順便將之前的中文utf-8修改以及官版mailwatch 1.05的增修部份整併, 整個web目錄打包. 下載:
http://www.box.net/shared/bpe4gc8deprpem3oygrb

mysar

Squid3 安裝完成後接下來就是LOG分析.目前測試過比較即時的就是squidview跟mysar. squidview可在console即時觀看log及簡易統計但無資料庫功能, mysar雖然沒那麼即時但是具有較完整的分析功能. 因此這邊採用mysar做為分析工具. 在經過一段時間統計後發現squid會產生一些欄位不全的LOG, 以至於欄位錯亂. 官網開發幾乎停滯, 目前原作者才剛找到別的開發者接手, 暫時只好用三腳貓的工夫自己改, 加上內部有使用AD網域順便增加部門欄位, 讓importer連到AD取得電腦所屬的組織單位(OU)當作部門, 當然也可以自行在網頁上修改, 不過只能一台台修改就是. 另外加上中文體的樣版, 資料庫也改為UTF-8.

Mysar 2.1.4 jccc修改版. 修改內容

  1. 新增”部門”欄位, 可網頁主機資訊增加部門, 或由 myar-resolver.php取得(需有AD環境並開啟功能)
  2. 修改mysar-importer.php, 忽略有問題的 squid log 避免欄位錯亂
  3. 資料庫改為UTF-8
  4. 新增中文樣版並作為預設樣版

PS: 資料庫預設語言修改所以只適用新安裝

下載: mysar-2.1.4jccc.tar.bz2

Netscreen + Squid (Transparent) + c-icap + ClamAV

架構圖:

squid

目的:
原始流往網際網路的WEB流量經過防火牆Netscreen-25重新導向內部的Squid proxy伺服器並提供掃毒需求.

方法:
透通式SQUID可以省去客戶端設定的麻煩, 但需將 TCP 80 流量重新導向. Netscreen 支援兩種導向方式, 介紹如下

  • NAT-DST(DNAT)
    NETSCREEN NAT-DST的限制如下(來源:ScreenOS參考指南)
    「注意 : 原始目的地IP位址及已轉譯的目的地IP位址必須在相同的安全區內」
    由於向外WEB流量在untrust (any), 因此SQUID伺服器也必須在DMZ或有MIP, 且必須允許untrust介面IP流向SQUID位址DMZ/MIP TCP:3128流量. 另外內部流量向untrust的TCP:80封包必須DNAT到SQUID伺服器MIP位址的TCP:3128. 該方式會造成統計SQUID流量時看到的都是防火牆作NAT介面的外部IP, 無法統計實際流量. 原本想把SQUID 內部IP加進untrust-vr, 然後DNAT到內部IP 也是不可行. 此方式可以在舊版ScreenOS(5.4之前)使用.
  • PBR(Policy Base Routing. Screenos 5.4.0以上支援)
    此方法可以直接將特定服務流量到向指定的IP但是不支援PAT, 也就是可以轉寄流量但是不能更改目的埠, 因此需要搭配在SQUID主機上執行IPTABLES以達成目的埠轉換..

考量流量分析精確性, Server安全性及架構, 這裡採用PBR以達到cache目的

  1. CentOS5主機安裝Squid 3.1
    上http://rpm.pbone.net搜尋下載squid3-3.1.8-1.el5.pp.i386.rpm
    [root@centos5]# rpm –Uvh squid3-3.1.8-1.el5.pp.i386.rpm
    修改 /etc/squid/squid.conf (只列出重點設定)

    #上層伺服器
    cache_peer proxy.hinet.net parent 80 0 no-query no-digest no-netdb-exchange

    #將連到youtube.com要求轉發給上層伺服器
    cache_peer_domain proxy.hinet.net .youtube.com

    #預設存取設定
    acl manager proto cache_object
    acl localhost src 127.0.0.1/32 ::1
    acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1
    acl localnet src 10.0.0.0/8     # RFC1918 possible internal network
    acl localnet src 172.16.0.0/12  # RFC1918 possible internal network
    acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
    acl localnet src fc00::/7       # RFC 4193 local private network range
    acl localnet src fe80::/10      # RFC 4291 link-local (directly plugged) machines

    # ACL for Youtube
    acl youtube dstdomain .youtube.com

    acl SSL_ports port 443
    acl Safe_ports port 80          # http
    acl Safe_ports port 21          # ftp
    acl Safe_ports port 443         # https
    acl Safe_ports port 70          # gopher
    acl Safe_ports port 210         # wais
    acl Safe_ports port 1025-65535  # unregistered ports
    acl Safe_ports port 280         # http-mgmt
    acl Safe_ports port 488         # gss-http
    acl Safe_ports port 591         # filemaker
    acl Safe_ports port 777         # multiling http
    acl CONNECT method CONNECT

    # 讓Youtube 使用上層, 其餘由squid本身直接存取
    never_direct allow youtube
    http_access allow manager localhost
    http_access deny manager
    http_access deny !Safe_ports
    http_access deny CONNECT !SSL_ports
    http_access allow localnet
    http_access allow localhost

    # ssl代理
    ssl_bump deny localhost
    ssl_bump allow all
    http_access deny all

    # 透通代理http
    http_port 3128 intercept

    # 透通代理https.基本上不建議在透通模式下啟用.必須置換憑證以解密ssl流量, 因此需要正式憑證, 若使用測試憑證client端會跳出此網站不安全的訊息
    https_port 3129 intercept ssl-bump cert=/etc/pki/tls/certs/testcert.pem

    hierarchy_stoplist cgi-bin ?

    # 將儲存區上限改為1gb.
    cache_dir ufs /var/cache/squid 1000 16 256
    coredump_dir /var/cache/squid
    refresh_pattern ^ftp:           1440    20%     10080
    refresh_pattern ^gopher:        1440    0%      1440
    refresh_pattern -i (/cgi-bin/|\?) 0     0%      0
    refresh_pattern .               0       20%     4320

    #ICAP設定
    icap_enable on
    icap_preview_enable on
    icap_preview_size 128
    icap_send_client_ip on
    icap_service service_avi_req reqmod_precache 0 icap://localhost:1344/srv_clamav
    icap_service service_avi respmod_precache 1 icap://localhost:1344/srv_clamav
    adaptation_access service_avi_req allow all
    adaptation_access service_avi allow all

    #將錯誤顯示頁面設為中文
    error_default_language zh-tw

    設定開機即啟用服務

    [root@centos5]# chkconfig –add –level 2345 squid

  2. 設定iptables
    加入規則

    [root@centos5]# iptables -A PREROUTING -i eth0 -p tcp -m tcp -m multiport tcp -d 10.0.0.2 –dport 80,443 -j ACCEPT
    [root@centos5]# iptables -A PREROUTING -i eth0 -p tcp -m tcp ! -d localhost –dport 80 -j REDIRECT –to-port 3128
    [root@centos5]# iptables -A PREROUTING -i eth0 -p tcp -m tcp ! -d localhost –dport 443 -j REDIRECT –to-port 3129

    Squid伺服器本身有提供Web服務, 因此第一行需放行目的為本機IP的TCP 80,443封包, 第二行將連往網際網路TCP 80的封包重新導向Squid服務的TCP 3128. 第三行則將連往網際網路TCP 443的封包重新導向Squid服務的TCP 3129.
    啟動並儲存規則

    [root@centos5]# service iptables start
    [root@centos5]# iptables-save > /etc/sysconfig/iptables
    [root@centos5]# chkconfig –add –level 2345 iptables

  3. 設定NetScreen
    PBR流程
    policy3-1. 建立兩個acl存取名單. 第一組為來源IP是區域網路封包目標為網際網路網頁存取.第二組則為Squid伺服器本身的網際網路存取, 避免本身連向網路封包變成迴圈. CLI (指令模式)

    set access-list extended 1 src-ip 10.0.0.0/24 dst-port 80-80 protocol tcp entry 1
    set access-list extended 1 src-ip 10.0.0.0/24 dst-port 443-443 protocol tcp entry 2
    set access-list extended 2 src-ip 10.0.0.2/32 dst-port 80-80 protocol tcp entry 1
    set access-list extended 2 src-ip 10.0.0.2/32 dst-port 443-443 protocol tcp entry 2

    3-2. 第一組acl加入Http_Traffic群組(match-group), 第二組acl則加入Direct_Http_Traffic群組(match-group). CLI (指令模式)

    set match-group name Direct_Http_Traffic
    set match-group Direct_Http_Traffic ext-acl 2 match-entry 1
    set match-group name Http_Traffic
    set match-group Http_Traffic ext-acl 1 match-entry 1

    3-3. Tproxy的執行動作設定為當符合Http_Traffic群組的封包到達時直接送往Squid伺服器(10.0.0.2). Direct_Http則將符合Direct_Http_Traffic群組送往untrust介面(eth3). CLI (指令模式)

    set action-group name Tproxy
    set action-group Tproxy next-hop 10.0.0.2 action-entry 1
    set action-group name Direct_Http
    set action-group Direct_Http next-interface ethernet3 action-entry 1

    3-4. 建立政策(policy). 第一個先讓Squid本機連往網際網路, 若為其他客戶端則為順序2, 轉到Squid主機..

    set pbr policy name trust_policy
    set pbr policy trust_policy match-group Direct_Http_Traffic action-group Direct_Http 1
    set pbr policy trust_policy match-group Http_Traffic action-group Tproxy 2
    set pbr trust_policy
    exit

    3-5. 將政策連結到trust介面(eth1).CLI (指令模式)

    set interface ethernet1 pbr trust_policy

  4. 安裝Clamav
    #搭配MailScanner 因此安裝 Clamd

    [root@centos5]# yum install clamav clamav-db clamd

  5. 安裝c-icap
    上http://rpm.pbone.net搜尋下載c-icap , c-icap-modules的source rpm回來編譯

    [root@centos5]# rpmbuild –rebuild c-icap-0.1.1-1.el5.pp.src.rpm

    編譯完成後會有多個檔案主要安裝下面幾個
    c-icap-0.1.1-1.el5.pp.i386.rpm      # c-icap主程式
    c-icap-libs-0.1.1-1.el5.pp.i386.rpm   # library
    c-icap-progs-0.1.1-1.el5.pp.i386.rpm  # client程式
    c-icap-devel-0.1.1-1.el5.pp.i386.rpm  # 編譯c-icap-modules用
    下載的c-icap-modules並無開啟clamv, 需自行修改並編譯

    [root@centos5]# rpmbuild -i c-icap-modules-0.1.1-1.el5.pp.src.rpm
    [root@centos5]# cd /usr/src/redhat/SPECS

    更改c-icap-modules.spec檔案, 註釋掉」–without-clamav」

    CFLAGS=”${RPM_OPT_FLAGS} -fno-strict-aliasing” \
    –enable-shared                                \
    –with-bdb
    #       –without-clamav  # Still not in RedHat/CentOS

    重編

    [root@centos5]# rpmbuild -bb c-icap-modules-0.1.1-1.el5.pp.src.rpm
    [root@centos5]# cd ../RPMS/i386
    [root@centos5]# rpm –Uvh c-icap-modules-0.1.1-1.el5.rpm

    修改c-icap server設定 /etc/c-icap/c-icap.conf

    PidFile /var/run/c-icap/c-icap.pid
    CommandsSocket /var/run/c-icap/c-icap.ctl
    Timeout 300
    MaxKeepAliveRequests 100
    KeepAliveTimeout 600
    StartServers 3
    MaxServers 10
    MinSpareThreads     10
    MaxSpareThreads     20
    ThreadsPerChild     10
    MaxRequestsPerChild  0
    Port 1344
    ServerAdmin 你的管理員郵件
    ServerName 你的主機名稱
    TmpDir /var/tmp
    MaxMemObject 131072
    DebugLevel 1
    ModulesDir /usr/lib/c_icap
    ServicesDir /usr/lib/c_icap
    TemplateDir /usr/share/c_icap/templates/
    TemplateDefaultLanguage en
    LoadMagicFile /etc/c-icap/c-icap.magic
    RemoteProxyUsers off
    RemoteProxyUserHeader X-Authenticated-User
    RemoteProxyUserHeaderEncoded on
    #本機存取位址
    acl localhost src 127.0.0.1/255.255.255.255
    #所有位置
    acl all src 0.0.0.0/0.0.0.0
    #允許本機存取
    icap_access allow localhost
    #拒絕所有存取
    icap_access deny all
    #Log檔位置
    ServerLog /var/log/c-icap/server.log
    AccessLog /var/log/c-icap/access.log
    #以下三行設定病毒紀錄檔格式及位置
    acl VIRUS icap_resp_header{X-Infection-Found} /Type=.*/
    LogFormat viruslog “%tl, %>a %im %iu %is %{X-Infection-Found}<ih:”
    AccessLog /var/log/c-icap/viruses.log viruslog VIRUS
    Service echo srv_echo.so
    #開啟clamav模組掃瞄功能
    Include srv_clamav.conf

    修改c-icap-modules設定, 基本上維持預設值即可

    Service antivirus_module srv_clamav.so
    ServiceAlias  avscan srv_clamav?allow204=on&sizelimit=off&mode=simple
    srv_clamav.ScanFileTypes TEXT DATA EXECUTABLE ARCHIVE GIF JPEG MSOFFICE
    srv_clamav.SendPercentData 5
    srv_clamav.StartSendPercentDataAfter 2M
    srv_clamav.MaxObjectSize  5M
    srv_clamav.ClamAvTmpDir /var/tmp
    srv_clamav.ClamAvMaxFilesInArchive 0
    srv_clamav.ClamAvMaxFileSizeInArchive 100M
    srv_clamav.ClamAvMaxRecLevel 5

    此rpm所提供的init script以c-icap身份啟動, 經測試無法正常啟動.改以root啟動卻無問題, 因此修改/etc/sysconfig/c-icap

    #改掉下面這行, 將使用者改為root
    #RUN_AS=”c-icap”
    RUN_AS=”root”

    也可以到官網http://c-icap.sourceforge.net 下載最新0.1.2版自行安裝, 但原始package並未包含init script/syconfig/logrotate檔.
    設定開機啟動

    [root@centos5]# chkconfig –add –level 2345 c-icap

  6. 啟動相關服務

    [root@centos5]# service c-icap start

    [root@centos5]# service squid start

  7. 測試掃毒功能

    [root@centos5]# c-icap-client -f /path_to_clamav/test/clam.exe -s “srv_clamav?allow204=on&force=on&sizelimit=off&mode=simple”
    ICAP server:localhost, ip:127.0.0.1, port:1344
    <html>
    <head>
    <!–C-ICAP/0.1.2 srvClamAV module –>
    </head>
    <body>
    <H1>VIRUS FOUND</H1> You try to upload/download a file that contain the virus<br>
    ClamAV-Test-File
    <p>This message generated by C-ICAP/0.1.2 srvClamAV/antivirus module
    <!– And this is a silly HTML comment just to make this error bigger than 512 bytes
    is allowed to be displayed in IE. Yes, IE has a “feature” which does not allow
    error messages smaller than 512 bytes to be displayed, because they are not considered
    “friendly” enough.
    (Hmm…I think this stupid comment is better than embedding viruses or porn images in this error message like a bad guy suggested me!)–> </body>

    顯示掃到毒(clamav原始package內附的樣本)

  8. 結論:大致上需要的功能皆已完成, Squid部份可以進行校調以增加cache命中率.