Haproxy1.6 configuration file

Standard
global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        user haproxy
        group haproxy
        maxconn     6000
        daemon
        tune.ssl.default-dh-param 2048
 
defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
 
listen stats
   bind 0.0.0.0:8080
   mode http
   stats enable
   stats hide-version
   stats realm Haproxy\ Statistics
   stats uri /stats
   stats auth username:password
 
frontend http_yemaosheng
    bind *:80
    mode http
    default_backend web-nodes
 
frontend https_yemaosheng
     #cat yemaosheng.crt yemaosheng.key | tee yemaosheng.pem
     bind *:443 ssl crt /root/yemaosheng.pem
     mode http
     option httpclose
     option forwardfor
     reqadd X-Forwarded-Proto:\ https
     default_backend web-nodes
 
backend web-nodes
    mode http
    balance roundrobin
    option forwardfor
    server web-1 10.0.1.2:80 check
    server web-2 10.0.1.3:80 check

Export Azure network security groups using PowerShell

Standard
> Install-Module AzureRM
 
> Import-Module AzureR
Error:
  Import-Module : File C:\Program Files\WindowsPowerShell\Modules\AzureRM\4.2.1\AzureRM.psm1,...
 
The PowerShell should work with the RemoteSigned policy in any case.
> Get-ExecutionPolicy -List
> Get-ExecutionPolicy -Scope CurrentUser
> Set-ExecutionPolicy RemoteSigned
 
> Import-Module AzureRM
> Login-AzureRmAccount
 
> Get-AzureRmSubscription
  Name     : BizSpark
  Id       : 1e573f03-6685-xxxx-bcb0-xxx
  TenantId : 517c8f98-6209-xxxx-9aca-xxx
  State    : Enabled
 
  Name     : Microsoft Azure Sponsorship
  Id       : 61719d1b-1c44-xxxx-a985-xxx
  TenantId : 517c8f98-6209-xxxx-9aca-xxx
  State    : Enabled
 
> Select-AzureRmSubscription -SubscriptionId "61719d1b-1c44-xxxx-a985-xxx"
 
> Get-AzureRmNetworkSecurityGroup -Name NSG_NAME -ResourceGroupName ResourceGroupName | Get-AzureRmNetworkSecurityRuleConfig | Select * | > Export-Csv -NoTypeInformation -Path C:\NSGExport.csv

ZabbixからSlackに通知を送る

Standard

関連かんれんリソース:
https://github.com/ericoc/zabbix-slack-alertscript
を使います。基本的きほんてきにはこちらのreadme通りに設定せっていします。

Slack側の設定
https://yemaosheng.slack.com/services/new/incoming-webhook
からincoming web hookを作成さくせいし、”Webhook URL”を確認かくにんしておきます。

テストURL:

curl -X POST --data-urlencode 'payload={"channel": "#alert", "username": "webhookbot", "text": "This is posted to #alert and comes from a bot named webhookbot.", "icon_emoji": ":ghost:"}' https://hooks.slack.com/services/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

使用免费的SSL

Standard

公司收的一大堆论坛都要加SSL,每个都要购买的话会是一笔不小的费用。
所以准备全部使用Let’s Encrypt的免费SSL。

wget -O -  https://get.acme.sh | sh
cd .acme.sh/
#确保通过域名可访问到/var/www/yemaosheng/htdocs/.well-known/下的内容
./acme.sh --issue -d yemaosheng.com -d www.yemaosheng.com -w /var/www/yemaosheng/htdocs
[Tue Mar  7 21:19:34 CST 2017] Multi domain='DNS:www.yemaosheng.com'
[Tue Mar  7 21:19:34 CST 2017] Getting domain auth token for each domain
[Tue Mar  7 21:19:34 CST 2017] Getting webroot for domain='yemaosheng.com'
[Tue Mar  7 21:19:34 CST 2017] Getting new-authz for domain='yemaosheng.com'
[Tue Mar  7 21:19:36 CST 2017] The new-authz request is ok.
[Tue Mar  7 21:19:36 CST 2017] Getting webroot for domain='www.yemaosheng.com'
[Tue Mar  7 21:19:36 CST 2017] Getting new-authz for domain='www.yemaosheng.com'
[Tue Mar  7 21:19:36 CST 2017] The new-authz request is ok.
[Tue Mar  7 21:19:37 CST 2017] yemaosheng.com is already verified, skip http-01.
[Tue Mar  7 21:19:37 CST 2017] Verifying:www.yemaosheng.com
[Tue Mar  7 21:19:39 CST 2017] Success
[Tue Mar  7 21:19:39 CST 2017] Verify finished, start to sign.
[Tue Mar  7 21:19:40 CST 2017] Cert success.
-----BEGIN CERTIFICATE-----
MIIFFzCCA............FlYV3RaDYYpw=
-----END CERTIFICATE-----
[Tue Mar  7 21:19:40 CST 2017] Your cert is in  /root/.acme.sh/yemaosheng.com/yemaosheng.com.cer 
[Tue Mar  7 21:19:40 CST 2017] Your cert key is in  /root/.acme.sh/yemaosheng.com/yemaosheng.com.key 
[Tue Mar  7 21:19:40 CST 2017] The intermediate CA cert is in  /root/.acme.sh/yemaosheng.com/ca.cer 
[Tue Mar  7 21:19:40 CST 2017] And the full chain certs is there:  /root/.acme.sh/yemaosheng.com/fullchain.cer
 
crontab -l
7 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
 
vi /etc/httpd/conf.d/ssl.conf
...
<VirtualHost *:443>
        DocumentRoot "/var/www/yemaosheng/htdocs"
        ServerName yemaosheng.com
 
        SSLEngine on
        SSLProtocol all -SSLv2 -SSLv3
        SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH EDH+aRSA !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"
        SSLCertificateFile "/root/.acme.sh/yemaosheng.com/yemaosheng.com.cer"
        SSLCertificateKeyFile "/root/.acme.sh/yemaosheng.com/yemaosheng.com.key"
        SSLCertificateChainFile "/root/.acme.sh/yemaosheng.com/fullchain.cer"
        ...
</VirtualHost>
...

How to clone a Azure VM

Standard

run on your sample-vm

waagent -deprovision+user

run on your azure-cli env

$rgName = "VMTestGroup"
$template = "Template-test.json"
$vmName = "VMTest"
$vhdName = "VHDTest"
 
azure vm deallocate -g $rgName -n $vmName
azure vm generalize $rgName -n $vmName
azure vm capture $rgName $vmName $vhdName -t $template
 
# the $template should looks like this. and you have to change 'newvmname' before use.
...
         "storageProfile": {
          "dataDisks": [
            {
              "caching": "ReadOnly",
              "vhd": {
                "uri": "https://yourdiskname.blob.core.windows.net/vhds/dataDisk-0.newvmname.vhd"
              },
              "image": {
                "uri": "https://yourdiskname.blob.core.windows.net/system/Microsoft.Compute/Images/vhds/yourcapturedvmname-dataDisk-0.ff60129b-...3cf59bf9315a.vhd"
              },
              "createOption": "FromImage",
              "name": "yourcapturedvmname-dataDisk-0.ff60129b-4ec5-4dcd-ae97-3cf59bf9315a.vhd",
              "lun": 0
            }
          ],
          "osDisk": {
            "caching": "ReadWrite",
            "vhd": {
              "uri": "https://yourdiskname.blob.core.windows.net/vhds/osDisk.newvmname.vhd"
            },
            "image": {
              "uri": "https://yourdiskname.blob.core.windows.net/system/Microsoft.Compute/Images/vhds/yourcapturedvmname-osDisk.ff60129b-...3cf59bf9315a.vhd"
            },
            "createOption": "FromImage",
            "name": "yourcapturedvmname-osDisk.ff60129b-4ec5-4dcd-ae97-3cf59bf9315a.vhd",
            "osType": "Linux"
          }
        },
...
 
 
azure group deployment create $rgName MyDeployment -f Template-test-modified.json
    info:    Executing command group deployment create
    info:    Supply values for the following parameters
    vmName: NewVmName
    adminUserName: username
    adminPassword: password
    networkInterfaceId: /subscriptions/61719d1b-...ab74b6f77865/resourceGroups/VMTestGroup/providers/Microsoft.Network/networkInterfaces/YourNetworkInterfaceName
 
#If you do not have an existing NetworkInterface, you need create first. 
azure network nic create $rgName YourNetworkInterfaceName -k default -m YourSubnetVnetName  -l "westus2"

Percona Monitoring Plugins for Zabbix3

Standard
#Install
apt-get install percona-zabbix-templates
cp /var/lib/zabbix/percona/templates/userparameter_percona_mysql.conf /etc/zabbix/zabbix_agentd.conf.d/
#Configure 
vi /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php
...
$mysql_user = 'uid';
$mysql_pass = 'pwd';
...
#Test
/var/lib/zabbix/percona/scripts/get_mysql_stats_wrapper.sh gg

zbx_percona_mysql_template

Using SaltStack to deploy Auto-scaling EC2

Standard

SaltStack Master: 172.66.1.100

Create AMI by default VM:

root@ip-x.x.x.x:~# cat /etc/rc.local
/root/PkgInit.sh;
/root/SaltMinionInit.sh;
/root/SaltCall.sh;
 
root@ip-x.x.x.x:~# cat /root/PkgInit.sh 
add-apt-repository ppa:saltstack/salt -y;
apt-get update;
apt-get install salt-minion -y;
apt-get install awscli -y;
 
root@ip-x.x.x.x:~# cat /root/SaltMinionInit.sh
INSTANCE_ID=$(ec2metadata --instance-id);
REGION=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | grep region | awk -F\" '{print $4}');
TAG=$(aws ec2 describe-tags --filters "Name=resource-id,Values=$INSTANCE_ID" --region=$REGION --output=text --max-items=1 | cut -f5);
/bin/echo -e "master: 172.66.1.100\ngrains:\n  roles:\n    - "$TAG > /etc/salt/minion;
service salt-minion restart;
 
root@ip-x.x.x.x:~# cat /root/SaltCall.sh
sleep 15s;
salt-call state.highstate;

Setup Saltstack Master:

root@ip-172-66-1-100:~# add-apt-repository ppa:saltstack/salt
root@ip-172-66-1-100:~# apt-get update
root@ip-172-66-1-100:~# apt-get install salt-master
root@ip-172-66-1-100:~# cat /etc/salt/master | grep -v '^#' | grep -v '^$'
file_roots:
  base:
    - /srv/salt
pillar_roots:
  base:
    - /srv/pillar
reactor:
  - 'salt/auth':
    - /srv/reactor/auth-pending.sls
 
# Automating Key Acceptance
# salt-run state.event pretty=True
root@ip-172-66-1-100:~# cat /srv/reactor/auth-pending.sls
{% if 'act' in data and data['act'] == 'pend' and data['id'].startswith('ip-172') %}
minion_add:
  wheel.key.accept:
    - match: {{ data['id'] }}
{% endif %}
 
# Get grains item
root@ip-172-66-1-100:~# salt '*' grains.item os
ip-172-66-2-214:
    ----------
    os:
        Ubuntu
ip-172-66-4-93:
    ----------
    os:
        Ubuntu
root@ip-172-66-1-100:/srv/reactor# salt '*' grains.item roles
ip-172-66-2-214:
    ----------
    roles:
        - YeMaosheng_com
ip-172-66-4-93:
    ----------
    roles:
        - YeMaosheng_com
 
root@ip-172-66-1-100:~# salt -G 'roles:YeMaosheng_com' state.highstate -t 60 test=True
root@ip-172-66-1-100:~# salt -G 'roles:YeMaosheng_com' state.highstate
root@ip-172-66-1-100:~# salt-run manage.down removekeys=True
root@ip-172-66-1-100:~# salt-run state.event pretty=True

网站所用EC2的安装及发布配置

├── pillar
│   ├── yemaosheng_com
│   │   ├── nginx.sls
│   │   ├── php56.sls
│   │   └── website.sls
│   └── top.sls
├── reactor
│   └── auth-pending.sls
└── salt
    ├── crontab
    │   └── init.sls
    ├── mysql-client
    │   └── init.sls
    ├── nginx
    │   ├── configs
    │   │   └── yemaosheng_com
    │   │       ├── blockrules.conf
    │   │       ├── nginx.conf
    │   │       └── sites-enabled
    │   │           └── yemaosheng.com
    │   └── init.sls
    ├── php56
    │   ├── configs
    │   │   └── yemaosheng_com
    │   │       └── php5-fpm
    │   │           └── www.conf
    │   └── init.sls
    ├── top.sls
    ├── website
    │   ├── configs
    │   │   └── yemaosheng_com
    │   │       ├── dhparam.pem
    │   │       └── sslkey
    │   └── init.sls
    └── websitefiles
        └── yemaosheng_com -> /var/www/yemaosheng_com
 
cat /srv/salt/top.sls 
base:
 'roles:yemaosheng_com':
 - match: grain
 - mysql-client
 - php56
 - nginx
 - website
 - crontab
 
cat /srv/pillar/top.sls 
base : 
 'roles:yemaosheng_com':
 - match: grain
 - yemaosheng_com.nginx
 - yemaosheng_com.php56
 - yemaosheng_com.website
 
cat /srv/pillar/yemaosheng_com/nginx.sls 
nginx_conf: nginx/configs/yemaosheng_com/nginx.conf
nginx_site-enable: nginx/configs/yemaosheng_com/sites-enabled
 
cat /srv/salt/nginx/init.sls 
{% set site_name = pillar['site_name'] %}
 
nginx:
  pkg:
    - name: nginx
    - installed
 
nginx_conf:
  service.running:
    - name: nginx
    - enable: True
    - reload: True
    - watch:
      - file: /etc/nginx/*
  file.managed:
    - name: /etc/nginx/nginx.conf
    - source: salt://{{ pillar['nginx_conf'] }}
    - user: root
    - group: root
    - mode: '0640'
    - require:
      - pkg: nginx
 
{% if site_name == 'yemaosheng_com' %}
upload_sslkey_to_nginx:
  file.recurse:
    - name: /srv/ssl
    - user: root
    - group: root
    - file_mode: '0644'
    - source: salt://website/configs/yemaosheng_com/sslkey
    - include_empty: True
 
upload_dhparam_to_nginx:
  file.managed:
    - name: /etc/nginx/dhparam.pem
    - source: salt://website/configs/yemaosheng_com/dhparam.pem
    - user: root
    - group: root
    - mode: '0644'
    - require:
      - pkg: nginx
{% endif %}
 
/etc/nginx/sites-enabled:
  service.running:
    - name: nginx
    - enable: True
    - reload: True
    - watch:
      - file: /etc/nginx/sites-enabled
  file.recurse:
    - name: /etc/nginx/sites-enabled
    - user: root
    - group: root
    - dir_mode: 2775
    - file_mode: '0644'
    - source: salt://{{ pillar['nginx_site-enable'] }}
    - include_empty: True
    - clean: True
    - require:
      - pkg: nginx

AWS VPC point to point with gre tunnel

Standard

related AWS VPC通过IPsec连接不同Region

AWS China EC2:

root@ip-10-33-30-103:/home/ubuntu# cat /etc/network/interfaces.d/gre1.cfg
auto gre1
iface gre1 inet tunnel
  mode gre
  netmask 255.255.255.255
  address 10.0.0.2
  dstaddr 10.0.0.1
  endpoint 52.63.189.251
  local 10.33.30.103
  ttl 255
 
root@ip-10-33-30-103:/home/ubuntu# route add -net 172.33.0.0 netmask 255.255.0.0 gw 10.0.0.2

AWS Sydney EC2:

root@ip-172-33-1-190:/home/ubuntu# cat /etc/network/interfaces.d/gre1.cfg 
auto gre1
iface gre1 inet tunnel
  mode gre
  netmask 255.255.255.255
  address 10.0.0.1
  dstaddr 10.0.0.2
  endpoint 54.222.193.171
  local 172.33.1.190
  ttl 255
 
root@ip-172-33-1-190:/home/ubuntu# route add -net 10.33.0.0 netmask 255.255.0.0 gw 10.0.0.1

Mikrotik L2TP with IPsec for mobile clients

Standard

转自: http://www.firstdigest.com/2015/01/mikrotik-l2tp-with-ipsec-for-mobile-clients/

1.Add a new pool

GUI
IP > Pool
Name: L2TP-Pool
Adresses: 172.31.86.1-172.31.86.14
Next Pool: None
 
CLI
/ip pool add name="L2TP-Pool" ranges=172.31.86.1-172.31.86.14

L2TP Configuration

1. Configure L2TP Profile

GUI
PPP > Profiles
Name: l2tp-profile
Local Address: L2TP-Pool
Remote Address: L2TP-Pool
DNS Server: 8.8.8.8
Change TCP MSS: yes
Use Encryption: required
 
CLI
/ppp profile add name=l2tp-profile local-address=L2TP-Pool remote-address=L2TP-Pool use-encryption=required change-tcp-mss=yes dns-server=8.8.8.8

2. Add a L2TP-Server

GUI
PPP > Interface > L2TP Server
Enabled: Checked
Max MTU: 1460
Max MRU: 1460
Keepalive Timeout: 30
Default Profile: mschap2
Use IPsec: Checked
IPsec Secret: MYKEY
 
CLI
/interface l2tp-server server set authentication=mschap2 default-profile=l2tp-profile enabled=yes ipsec-secret=MYKEY max-mru=1460 max-mtu=1460 use-ipsec=yes

3. Add PPP Secrets

GUI
PPP > Secrets
Enabled: Checked
Name: MYUSER
Password: MYPASSWORD
Service: l2tp
Profile: l2tp-profile
 
CLI
/ppp secret add name=MYUSER password=MYPASSWORD service=l2tp profile=l2tp-profile

IPsec Configuration

1. IPsec Proposals

GUI
IPsec > Proposals
Enabled: Checked
Name: L2TP-Proposal
Auth. Algorithm: sha1
Encr. Algorithm: 3des, aes-256 cbc
PFS Group: none
 
CLI
/ip ipsec proposal add name=L2TP-Proposal auth-algorithms=sha1 enc-algorithms=3des,aes-256-cbc pfs-group=none

2. IPsec Peers

GUI
IPsec > Peers
Enabled: Checked
Address: 0.0.0.0
Auth. Method: pre shared key
Secret: MYKEY
Policy Template Group: default
Exchange Mode: main l2tp
Send Initial Contact: Checked
NAT Traversal: Checked
My ID: auto
Proposal check: obey
Hash Algorithm: sha1
Encryption Algorithm: 3des, aes-256
DH Group: modp1024
Generate policy: port override
 
CLI
/ip ipsec peer add address=0.0.0.0/0 port=500 auth-method=pre-shared-key secret="MYKEY" generate-policy=port-override exchange-mode=main-l2tp send-initial-contact=yes nat-traversal=yes hash-algorithm=sha1 enc-algorithm=3des,aes-256 dh-group=modp1024

3. IPsec Policies

GUI
Enabled: Checked
Src. Address: ::/0
Dst. Address: ::/0
Protocol: 255(all)
Template: Checked
Group: default
Action: encrypt
Level: require
IPsec Protocols: esp
Tunnel: Not checked
SA Src. Address: 0.0.0.0
SA Dsr. Address: 0.0.0.0
Proposal: L2TP-Proposal
 
CLI
/ip ipsec policy add src-address=::/0 dst-address=::/0 protocol=all template=yes group=default action=encrypt level=require ipsec-protocols=esp tunnel=no sa-src-address=0.0.0.0 sa-dst-address=0.0.0.0 proposal=L2TP-Proposal

PS:
因为同事们在家里连国外的VPN不太稳,所以用它从园区分给公司的IP上绕一绕。
具体可见之前发的那贴: http://yemaosheng.com/?p=1587

网站指向不同路径的nginx配置

Standard
upstream fastcgi_backend {
    server 127.0.0.1:9000;
    server unix:/var/run/php5-fpm.sock;
    keepalive 10;
}
...
server {
  ...
  ...
  location ~ \.php {
    set $php_root /var/www/website/abc/public;
    include /etc/nginx/fastcgi_params;
 
    if ($request_uri ~ /(api/user/photos|api/user/posts) ) {
      set $php_root /var/www/website/rest/public;
    }
 
    if ($request_uri ~ /api/user/(photos|posts|links) ) {
      set $php_root /var/www/website/rest/public;
    }
 
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_param PATH_TRANSLATED $php_root$fastcgi_path_info;
    fastcgi_param SCRIPT_NAME $fastcgi_script_name;
    fastcgi_param SCRIPT_FILENAME $php_root$fastcgi_script_name;
    fastcgi_pass fastcgi_backend;
    fastcgi_index index.php;
  }
  ...
}