08. openssl-1.1.1d(TLS1.3対応) [さくらのVPS/CentOS7]

・openssl-1.1.1d の用途

  1. postfix の TLS1.3 対応
  2. nginx の TLS1.3 対応

・openssl-1.1.1d のインストール

#-- 変数に必要な値を代入
VERSION=1.1.1d

#-- 作業ディレクトリの作成
mkdir -p ~/work/src
cd ~/work/src

#-- build に必要なパッケージのインストール
yum -y install perl-core zlib-devel

#-- source のダウンロード
curl -O -L https://www.openssl.org/source/openssl-${VERSION}.tar.gz
tar xvzf openssl-${VERSION}.tar.gz && cd openssl-${VERSION}

#-- build と install
./config --prefix=/usr/local/openssl-${VERSION} shared zlib
make
make install

#-- ライブラリパスに追加
ln -s openssl-${VERSION} /usr/local/openssl
echo /usr/local/openssl/lib >> /etc/ld.so.conf.d/openssl.conf
ldconfig

06. メールサーバ構築(2) – clamav [さくらのVPS/CentOS7]

・clamav-milter の用途

  1. 送信/受信メールのウィルススキャン (rspamd+calmav)
#-- 変数に必要な値を代入
DOMAIN=masdon.life

#-- clamav-milter のインストール
yum install -y clamav clamav-server-systemd clamav-update

#- Virus Database の更新
freshclam

#- clamd の設定
mkdir /var/log/clamd
chown clamscan /var/log/clamd

cp -p /etc/clamd.d/scan.conf{,.org}

cat <<_EOL_>/etc/clamd.d/scan.conf
LogFile /var/log/clamd/clamd.log
LogFileMaxSize 0
LogTime yes
LogSyslog yes
PidFile /var/run/clamd.scan/clamd.pid
TemporaryDirectory /var/tmp
DatabaseDirectory /var/lib/clamav
LocalSocket /var/run/clamd.scan/clamd.sock
FixStaleSocket yes
MaxConnectionQueueLength 30
MaxThreads 50
ReadTimeout 300
User clamscan
ScanPE yes
ScanELF yes
ScanOLE2 yes
ScanMail yes
ScanArchive yes
ArchiveBlockEncrypted no
_EOL_

#-- clamd の起動
systemctl enable clamd@scan 

#-- 2019/10/15の時点で私のテスト環境で clamd の起動に 約5分かかり、systemd の timeout (90秒)で起動に失敗する。タイムアウトを 5分に変更する
grep ^TimeoutSec /lib/systemd/system/clamd@.service >/dev/null || echo "TimeoutSec = 5min" >> /lib/systemd/system/clamd@.service
systemctl daemon-reload

systemctl start clamd@scan 

07. メールサーバ構築(3) – rspamd [さくらのVPS/CentOS7]

・rspamd の用途

  1. メール送信/転送時に DKIM/ARC署名
  2. メール受信時に SPF/DKIM/DMARC/ARC認証
  3. メール受信時に Virus/Spam Check (採点結果をヘッダーに追加)

・rspamd のインストール

#-- rspamd.com の repository を登録
curl https://rspamd.com/rpm-stable/centos-7/rspamd.repo > /etc/yum.repos.d/rspamd.repo
rpm --import https://rspamd.com/rpm-stable/gpg.key

#-- rspamd と redis のインストール
yum install -y rspamd redis

mkdir /etc/rspamd/local.d/keys/

#-- rspamd の設定
cat <<'_EOL_'> /etc/rspamd/local.d/options.inc
filters = "chartable,dkim,spf,surbl,regexp,fuzzy_check";
check_all_filters = true;
_EOL_

cat <<'_EOL_'> /etc/rspamd/local.d/milter_headers.conf
use = ["x-spamd-result","x-rspamd-server","x-rspamd-queue-id","authentication-results","x-spam-level","x-virus"];
#use = ["authentication-results"];
authenticated_headers = ["authentication-results"];
_EOL_

cat <<'_EOL_'> /etc/rspamd/local.d/redis.conf
servers = "127.0.0.1";
_EOL_

cat <<'_EOL_'> /etc/rspamd/local.d/actions.conf
reject = null;
add_header = 2.0 ;
greylist = null;
_EOL_

cat <<'_EOL_'> /etc/rspamd/local.d/greylist.conf
enabled = false
_EOL_

cat <<'_EOL_'> /etc/rspamd/local.d/phishing.conf
openphish_enabled = true;
phishtank_enabled = true;
_EOL_

cat <<_EOL_> /etc/rspamd/local.d/antivirus.conf
clamav {
  action  = "reject";
  type    = "clamav";
  servers = "/var/run/clamd.scan/clamd.sock";
  symbol = "CLAM_VIRUS";
  patterns {
    #symbol_name = "pattern";
    JUST_EICAR = "^Eicar-Test-Signature$";
  }
}
_EOL_

#-- clamd.sock にアクセスできるように group に追加
usermod -aG clamscan _rspamd
usermod -aG virusgroup _rspamd

cat <<'_EOL_'> /etc/rspamd/local.d/url_reputation.conf
enabled = true;

# Key prefix for redis - default "Ur."
key_prefix = "Ur.";

# Symbols to insert - defaults as shown
symbols {
  white = "URL_REPUTATION_WHITE";
  black = "URL_REPUTATION_BLACK";
  grey = "URL_REPUTATION_GREY";
  neutral = "URL_REPUTATION_NEUTRAL";
}

# DKIM/DMARC/SPF allow symbols - defaults as shown
foreign_symbols {
  dmarc = "DMARC_POLICY_ALLOW";
  dkim = "R_DKIM_ALLOW";
  spf = "R_SPF_ALLOW";
}

# SURBL metatags to ignore - default as shown
ignore_surbl = ["URIBL_BLOCKED", "DBL_PROHIBIT", "SURBL_BLOCKED"];

# Amount of samples required for scoring - default 5
threshold = 5;

#Maximum number of TLDs to update reputation on (default 1)
update_limit = 1;

# Maximum number of TLDs to query reputation on (default 100)
query_limit = 100;

# If true, try to find most 'relevant' URL (default true)
relevance = true;
_EOL_

#-- redisに書き込むデータ行数などの設定 10000以上が推奨
cat <<_EOL_> /etc/rspamd/local.d/history_redis.conf
servers         = 127.0.0.1:6379;
key_prefix      = "rs_history";
nrows           = 10000;
compress        = true;
subject_privacy = false;
_EOL_

#-- 拡張子の spam スコアを設定
cat <<_EOL_> /etc/rspamd/local.d/mime_types.conf
bad_extensions = {
    ace = 4,
    arj = 4,
    bat = 2,
    cab = 3,
    com = 2,
    exe = 1,
    jar = 2,
    lnk = 4,
    scr = 4,
};
bad_archive_extensions = {
    pptx = 0.1,
    docx = 0.1,
    xlsx = 0.1,
    pdf  = 0.1,
    jar  = 3,
    js   = 0.5,
    vbs  = 4,
};
archive_extensions = {
    zip = 1,
    arj = 1,
    rar = 1,
    ace = 1,
    7z  = 1,
    cab = 1,
};
_EOL_

#-- ホワイトリストの設定
cat <<'_EOL_'>/etc/rspamd/local.d/multimap.conf
WHITELIST_SENDER_DOMAIN {
  type = "from";
  map = "/etc/rspamd/local.d/whitelist_sender_domain.map";
  filter = "email:domain";
  score = -10.0
}
WHITELIST_IP {
  type = "ip";
  map = "/etc/rspamd/local.d/whitelist_ip.map";
  score = -10.0
}
_EOL_

#-- 変数に必要な値を代入
DOMAIN=masdon.life
IPV4=$(ip addr show eth0 | awk '/inet /{print $2}' | sed 's#/.*##')
IPV6=$(ip addr show eth0 | awk '/inet6 /&&/global/{print $2}' | sed 's#/.*##')

cat <<_EOL_>/etc/rspamd/local.d/whitelist_sender_domain.map
$DOMAIN
_EOL_

#-- これを設定しないとUser Unknown 時の MAILER DAEMONがSPAM扱いになってしまう。
cat <<_EOL_>/etc/rspamd/local.d/whitelist_ip.map
${IPV4}
${IPV6}
_EOL_

・DKIMで使用する秘密鍵と共通鍵の作成

#-- 変数に必要な値を代入
DOMAIN=masdon.life

#-- 鍵の生成
rspamadm dkim_keygen -d ${DOMAIN} -s default -b 2048
-----BEGIN PRIVATE KEY-----
....
....
....
....
-----END PRIVATE KEY-----
default._domainkey IN TXT ( "v=DKIM1; k=rsa; "
  "p=...."
  "...."
) ;

#-- 秘密鍵の登録 ----BEGIN〜 行から ----END〜 行までをファイルに記述する
vi /etc/rspamd/local.d/keys/default.${DOMAIN}.key
chmod 600 /etc/rspamd/local.d/keys/default.${DOMAIN}.key
chown _rspamd. /etc/rspamd/local.d/keys/default.${DOMAIN}.key

#-- 共通鍵の登録 default._domainkey〜 から ) ; 行までをゾーンファイルに記述し、シリアルを更新し nsd を再起動する
vi /etc/nsd/zone/${DOMAIN}.zone
systemctl restart nsd

#-- dkimの署名の設定
cat <<'_EOL_'> /etc/rspamd/local.d/dkim_signing.conf
# メーリングリストや転送の対応
allow_hdrfrom_mismatch = true;
sign_local = true;

# subdomain の sign 対応
use_esld = false;
try_fallback = false;

# sign 対象のヘッダー
sign_headers = '(o)from:(o)sender:(o)reply-to:(o)subject:(o)date:(o)message-id:(o)to:(o)cc:(o)mime-version:(o)content-type:(o)content-transfer-encoding:resent-to:resent-cc:resent-from:resent-sender:resent-message-id:(o)in-reply-to:(o)references:list-id:list-owner:list-unsubscribe:list-subscribe:list-post';

domain {
  masdon.life {
    # Private key path
    path = "/etc/rspamd/local.d/keys/$selector.$domain.key";
    # Selector
    selector = "default";
  }
}
_EOL_

#-- arc署名の設定
cat <<'_EOL_'> /etc/rspamd/local.d/arc.conf
# メーリングリストや転送の対応
allow_hdrfrom_mismatch = true;
sign_local = true;
use_domain = "envelope";

# subdomain の sign 対応
use_esld = false;
try_fallback = false;

sign_headers = "(o)from:(o)sender:(o)reply-to:(o)subject:(o)date:(o)message-id:(o)to:(o)cc:(o)mime-version:(o)content-type:(o)content-transfer-encoding:resent-to:resent-cc:resent-from:resent-sender:resent-message-id:(o)in-reply-to:(o)references:list-id:list-owner:list-unsubscribe:list-subscribe:list-post:dkim-signature";

domain {
  masdon.life {
    # Private key path
    path = "/etc/rspamd/local.d/keys/$selector.$domain.key";
    # Selector
    selector = "default";
  }
}
_EOL_

・Web interface のパスワード設定

#-- Web interface のパスワードを生成
PASSWORD=$(rspamadm pw -p ********)

cat <<_EOL_> /etc/rspamd/local.d/worker-controller.inc
password        = "${PASSWORD}";
enable_password = "${PASSWORD}";
_EOL_

・rspamd, redis 起動

systemctl enable rspamd redis
systemctl start rspamd redis

・Web interface用の nginx の設定ファイルを用意

mkdir -p /etc/nginx/conf.d/https.d
cat <<'_EOL_' > /etc/nginx/conf.d/https.d/rspamd.conf
  location ^~ /rspamd {
    location /rspamd/ {
      proxy_pass       http://localhost:11334/;
      proxy_set_header Host      $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
  }
_EOL_

05. メールサーバ構築(1) – dovecot [さくらのVPS/CentOS7]

・dovecot の用途

  1. LMTPサーバ (メール受信)
  2. Sieve(メールフィルタリング/メール転送)
  3. POP3/IMPA4サーバ (メール参照)
  4. ManageSieveサーバ

・dovecotをインストール

#-- 変数に必要な値を代入
DOMAIN=masdon.life
LDAP_SERVER=127.0.0.1 

#-- dovecot 2.3系の repository を登録
cat <<_EOL_> /etc/yum.repos.d/dovecot.repo
[dovecot-2.3-latest]
name=Dovecot 2.3 CentOS $releasever - \$basearch
baseurl=http://repo.dovecot.org/ce-2.3-latest/centos/\$releasever/RPMS/\$basearch
gpgkey=https://repo.dovecot.org/DOVECOT-REPO-GPG
gpgcheck=1
enabled=1
_EOL_

#-- dovecot のインストールと設定
yum install -y dovecot dovecot-pigeonhole
yum install -y openldap-devel expat-devel bzip2-devel zlib-devel

#- dovecot の設定
cat <<_EOL_> /etc/dovecot/local.conf
postmaster_address = postmater@${DOMAIN}
auth_mechanisms = plain login
deliver_log_format = from=%{from_envelope}, to=%{to_envelope}, size=%p, msgid=%m, delivery_time=%{delivery_time}, session_time=%{session_time}, %\$
disable_plaintext_auth = no
first_valid_uid = 97
mail_location = maildir:/var/dovecot/%Ld/%Ln
mail_plugins = \$mail_plugins zlib
plugin {
  sieve = /var/dovecot/%Ld/%Ln/dovecot.sieve
  sieve_extensions = +notify +imapflags +editheader +vacation-seconds
  sieve_max_actions = 32
  sieve_max_redirects = 10
  sieve_redirect_envelope_from = recipient
  sieve_vacation_min_period = 1h
  sieve_vacation_default_period = 7d
  sieve_vacation_max_period = 60d
  zlib_save = bz2
  zlib_save_level = 5
}
protocols = imap pop3 lmtp sieve
service imap-login {
  inet_listener imap {
    address = 127.0.0.1
  }
}
service lmtp {
  inet_listener lmtp {
    address = 127.0.0.1
    port = 24
  }
}
service pop3-login {
  inet_listener pop3 {
    address = 127.0.0.1
  }
}
service managesieve-login {
  inet_listener sieve {
    address = 127.0.0.1
  }
}
protocol lmtp {
  mail_plugins = \$mail_plugins sieve
}
protocol imap {
  mail_max_userip_connections = 20
}
ssl = no
ssl_cert =
ssl_key =
lda_mailbox_autocreate = yes
lmtp_save_to_detail_mailbox = yes
_EOL_

#- dovecot の認証設定
cp -p /etc/dovecot/conf.d/10-auth.conf{,.org}
cp -p /etc/dovecot/conf.d/auth-static.conf.ext{,.org}
sed -i 's/auth-system.conf.ext/auth-static.conf.ext/' /etc/dovecot/conf.d/10-auth.conf
cat <<_EOL_>/etc/dovecot/conf.d/auth-static.conf.ext
passdb {
  driver = static
  args = nopassword=y
}
# userdb {
#   driver = static
#   args = uid=dovecot gid=dovecot home=/var/dovecot/%Ld/%Ln allow_all_users=yes
# }
userdb {
  driver = ldap
  args = /etc/dovecot/dovecot-ldap.conf.ext
}
_EOL_

#- doveadm コマンドで ldap を参照する為の設定
cat <<_EOL_>/etc/dovecot/dovecot-ldap.conf.ext
hosts = ${LDAP_SERVER}
auth_bind = yes
base = ""
pass_attrs=mailRoutingAddress=User,userPassword=password
pass_filter = (&(objectClass=inetLocalMailRecipient)(mailRoutingAddress=%u))
iterate_attrs = mailRoutingAddress=user
iterate_filter = (&(objectClass=inetLocalMailRecipient)(mailRoutingAddress=*))
user_filter = (&(objectClass=inetLocalMailRecipient)(mailRoutingAddress=%u))
user_attrs = \
  =uid=dovecot, \
  =gid=dovecot, \
  =mail=maildir:/var/dovecot/%Ld/%Ln, \
  =home=/var/dovecot/%Ld/%Ln, \
  =acl_groups=%{ldap:publicMailboxGroup}, \
  =quota_rule=*:bytes=%{ldap:mailQuotaBytes}, \
  =quota_rule2=*:messages=%{ldap:mailQuotaMessages}
_EOL_
#-- acl_group, quota_rule, quota_rule2 については 別途必要な schema を定義する必要がある。acl_group は gr1,gr2 のようにカンマ区切りで値を設定する

#- mbox 用ディレクトリの作成
mkdir /var/dovecot
chown dovecot. /var/dovecot

#-- dovecot の起動
systemctl enable dovecot
systemctl start dovecot

04. LDAPサーバ構築 – openldap [さくらのVPS/CentOS7]

・LDAPサーバの用途

  1. メールアカウントの管理・認証
  2. Basic認証
  3. 各Webアプリケーションの認証

・LDAPサーバの構築

#-- 変数に必要な値を代入
ROOT_DN="cn=admin,dc=masdon,dc=life"
ROOT_PASSWORD="********"     #-- ROOT_DNのパスワードを入力
LDAP_MASTER=127.0.0.1
DOMAIN=masdon.life

#-- openldap と sendmail.schema をインストール
yum install -y openldap-servers openldap-clients sendmail-cf
ROOT_PW=$(slappasswd -s ${ROOT_PASSWORD})

#-- DB_CONFIG の作成
cat <<'_EOL_'> /var/lib/ldap/DB_CONFIG
set_cachesize 0 10485760 1
set_flags DB_LOG_AUTOREMOVE
set_lg_regionmax 262144
set_lg_bsize 2097152
_EOL_

#-- sendmail.schema を 指定のディレクトリへコピー
cp -p /usr/share/sendmail-cf/sendmail.schema /etc/openldap/schema/

#-- openldap の設定
cat <<_EOL_> /etc/openldap/slapd.conf
loglevel 0x4100
sizelimit -1
include  /etc/openldap/schema/corba.schema
include  /etc/openldap/schema/core.schema
include  /etc/openldap/schema/cosine.schema
include  /etc/openldap/schema/duaconf.schema
include  /etc/openldap/schema/dyngroup.schema
include  /etc/openldap/schema/inetorgperson.schema
include  /etc/openldap/schema/java.schema
include  /etc/openldap/schema/misc.schema
include  /etc/openldap/schema/nis.schema
include  /etc/openldap/schema/openldap.schema
include  /etc/openldap/schema/ppolicy.schema
include  /etc/openldap/schema/collective.schema
include  /etc/openldap/schema/sendmail.schema
allow bind_v2
pidfile  /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.args
moduleload syncprov.la
access to attrs=UserPassword
    by dn="${ROOT_DN}" write
    by self write
    by anonymous auth
    by * none
access to dn.regex="uid=.*,ou=Termed,dc=.*"
    by * none
access to *
    by * read
database config
access to *
    by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
    by * none
database monitor
access to *
    by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read
    by dn.exact="${ROOT_DN}" read
    by * none
database bdb
suffix  ""
checkpoint 1024 15
rootdn  "${ROOT_DN}"
rootpw  "${ROOT_PW}"
directory /var/lib/ldap
index objectClass   eq,pres
index uid           eq,pres,sub
index mailHost,mailRoutingAddress,mailLocalAddress,userPassword,sendmailMTAHost eq,pres
_EOL_

#-- slapd の起動オプションを変更
sed -i "s#^SLAPD_URLS=.*#SLAPD_URLS=\"ldap://${LDAP_MASTER}/\"#" /etc/sysconfig/slapd

#-- yum update で /etc/openlda/slapd.d が再作成されると slapd の起動が失敗するので定期的に確認して削除、同じく slapd.conf も slapd.conf.bakにリネームされるので元に戻す
mv /etc/openldap/slapd.d /etc/openldap/slapd.d.org
echo '* * * * * root rm -rf /etc/openldap/slapd.d >/dev/null 2>&1' > /etc/cron.d/${DOMAIN}-cron
echo '* * * * * root /usr/bin/mv -f /etc/openldap/slapd.conf.bak /etc/openldap/slapd.conf >/dev/null 2>&1' >>/etc/cron.d/${DOMAIN}-cron

#-- rsyslog の設定と logrotate の設定
echo "local4.*  /var/log/openldap" > /etc/rsyslog.d/openldap.conf
sed -i '1s#^#/var/log/openldap\n#' /etc/logrotate.d/syslog
systemctl restart rsyslog

#-- openldap を起動
systemctl enable slapd
systemctl start slapd

・ドメインと管理ユーザを登録

WORKDIR=~/work
mkdir -p ${WORKDIR}/ldap

#-- メールドメイン用の ldifファイルを作成
TMPDN=""
for x in $(for y in $(echo "${DOMAIN}" | sed 's/\./ /g')
do
    echo ${y}
done | tac)
do
    TMPDN="dc=${x}${TMPDN}"
cat <<_EOL_>>${WORKDIR}/ldap/init.ldif
dn: ${TMPDN}
objectClass: dcObject
objectClass: organization
dc: ${x}
o: ${DOMAIN}

_EOL_
    TMPDN=",${TMPDN}"
done

#-- 作成した ldif を LDAPサーバに登録
ldapadd -x -h ${LDAP_MASTER} -D "${ROOT_DN}" -w ${ROOT_PASSWORD} -f ${WORKDIR}/ldap/init.ldif

・管理者用メールアドレスの作成

#-- 管理者用メールアドレスを作成するスクリプトを作成
cat <<'_EOL_'> /usr/local/bin/create_admin_address.sh
#!/bin/bash
#
# usage)
# ./create_admin_address.sh domain

DOMAIN=$1
LDAP_MASTER=127.0.0.1
OUTBOUND_MTA_SERVER=127.0.0.1
STORE_SERVER=127.0.0.1
ROOT_DN="cn=admin,dc=masdon,dc=life"
ROOT_PASSWORD="********"  #-- ROOT_DNのパスワードを入力
WORKDIR=/root/work/ldap
ADMINS=" admin root postmaster abuse virus-report nobody "

ldapsearch -x -h ${LDAP_MASTER} -D "${ROOT_DN}" -w "${ROOT_PASSWORD}" > /dev/null 2>&1

if [ $? -ne 0 ]
then
  echo "invalid rootdn or rootpassword!!"
  exit 1
fi

mkdir -p ${WORKDIR}

ACCOUNT=$(echo ${ADMINS} | awk '{print $1}')
SSHAPW=$(slappasswd -s "${ROOT_PASSWORD}")
TMPDN=""
for x in $(for y in $(echo "${DOMAIN}" | sed 's/\./ /g')
do
  echo ${y}
done | tac)
do
  TMPDN="dc=${x}${TMPDN}"
  if [ $(ldapsearch -h ${LDAP_MASTER} -x -D "${ROOT_DN}" -w "${ROOT_PASSWORD}" -b "${TMPDN}" | grep -c ^dn:) -eq 0 ]
  then
    cat <<_EOF_>>${WORKDIR}/${DOMAIN}.ldif
dn: ${TMPDN}
objectClass: dcObject
objectClass: organization
dc: ${x}
o: ${DOMAIN}

_EOF_
  fi
  TMPDN=",${TMPDN}"
done

BASEDN=$(echo ${TMPDN} | sed 's/^,//')
BASEDN="ou=People,${BASEDN}"
TERMED=$(echo ${BASEDN} | sed 's/ou=People/ou=Termed/')

cat <<_EOF_>>${WORKDIR}/${DOMAIN}.ldif
dn: ${BASEDN}
ou: People
objectclass: organizationalUnit

dn: ${TERMED}
ou: Termed
objectclass: organizationalUnit

dn: uid=${ACCOUNT},${BASEDN}
objectclass: uidObject
objectClass: simpleSecurityObject
objectClass: inetLocalMailRecipient
objectClass: sendmailMTA
uid: ${ACCOUNT}
userPassword: ${SSHAPW}
mailHost: ${STORE_SERVER}
sendmailMTAHost: ${OUTBOUND_MTA_SERVER}
description: ${DOMAIN}
mailRoutingAddress: ${ACCOUNT}@${DOMAIN}
mailLocalAddress: ${ACCOUNT}@${DOMAIN}
_EOF_

for z in ${ADMINS}
do
  if [ "${z}" = "${ACCOUNT}" ]
  then
    continue
  fi
  echo "mailLocalAddress: ${z}@${DOMAIN}" >> ${WORKDIR}/${DOMAIN}.ldif
done
echo >> ${WORKDIR}/${DOMAIN}.ldif
ldapadd -x -h ${LDAP_MASTER} -D "${ROOT_DN}" -w "${ROOT_PASSWORD}" -f ${WORKDIR}/${DOMAIN}.ldif

_EOL_

#-- 管理者用メールアドレス作成
chmod 755 /usr/local/bin/create_admin_address.sh
/usr/local/bin/create_admin_address.sh ${DOMAIN}

・メールアドレスの作成

#-- メールアドレスを作成するスクリプトを作成
cat <<'_EOL_'> /usr/local/bin/create_mailaddress.sh
#!/bin/bash
# usage) ./create_mailaddress.sh <mailaddress>
ADDRESS=$1
LDAP_MASTER=127.0.0.1
STORE_SERVER=127.0.0.1
OUTBOUND_MTA_SERVER=127.0.0.1
ROOT_DN="cn=admin,dc=masdon,dc=life"
ROOT_PASSWORD="********"  #-- ROOT_DNのパスワードを入力
WORKDIR=/root/work/ldap

ldapsearch -x -h ${LDAP_MASTER} -D "${ROOT_DN}" -w ${ROOT_PASSWORD} > /dev/null 2>&1

if [ $? -ne 0 ]
then
	echo "invalid rootdn or rootpassword!!"
	exit 1
fi

if [ $(ldapsearch -x mailRoutingAddress=${ADDRESS} | grep -c "^mailRoutingAddress") -ne 0 ]
then
	echo "${ADDRESS} is already exist!!"
	exit 1
fi

mkdir -p ${WORKDIR}/ldap

ACCOUNT=$(echo ${ADDRESS} | awk -F@ '{print $1}')
if [ $(echo "${ADMINS}" | grep -c " ${ACCOUNT} ") -eq 1 ]
then
	echo "skip ${ADDRESS}"
	continue
fi
DOMAIN=$(echo ${ADDRESS} | awk -F@ '{print $2}')
mkdir -p ${WORKDIR}/${DOMAIN}
LDIFDIR=${WORKDIR}/${DOMAIN}
PASSWORD=$(mkpasswd -l 12 -d 3 -c 3 -C 3 -s 0)
SSHAPW=$(slappasswd -s ${PASSWORD})
BASEDN=""
for x in $(echo "${DOMAIN}" | sed 's/\./ /g')
do
	BASEDN="${BASEDN},dc=${x}"
done
BASEDN="ou=People${BASEDN}"

cat <<_EOF_>>${LDIFDIR}/${ACCOUNT}.ldif
dn: uid=${ACCOUNT},${BASEDN}
objectclass: uidObject
objectClass: simpleSecurityObject
objectclass: inetLocalMailRecipient
objectClass: sendmailMTA
uid: ${ACCOUNT}
userPassword: ${SSHAPW}
mailHost: ${STORE_SERVER}
sendmailMTAHost: ${OUTBOUND_MTA_SERVER}
mailRoutingAddress: ${ACCOUNT}@${DOMAIN}
mailLocalAddress: ${ACCOUNT}@${DOMAIN}

_EOF_

ldapadd -x -h ${LDAP_MASTER} -D "${ROOT_DN}" -w ${ROOT_PASSWORD} -f ${LDIFDIR}/${ACCOUNT}.ldif >/dev/null && echo ${PASSWORD}
_EOL_

chmod 755 /usr/local/bin/create_mailaddress.sh

・使用するアトリビュートの説明

アトリビュート説明
uidユーザ名admin
mailRoutingAddress配送先メールアドレス
認証に使用
admin@masdon.life
mailLocalAddressエイリアスメールアドレス
このアドレスに届いたメールは、
mailRoutingAddress の MBOX に配送される
admin@masdon.life
abuse@masdon.life
root@masdon.life
userPasswordパスワード{SSHA}ZiGSOKPJHbr9Jy2r2Q9hhJpdDv……
mailHostメール保存サーバ127.0.0.1
sendmailMTAHostメール送信サーバ127.0.0.1
description特にシステムで使用はしていない
ouPeople の場合は有効アカウント
Termed の場合は無効アカウント

これから構築するメールサーバはメールアドレスを LDAP に登録するだけですぐに使用できるようになる

03. Let’s EncryptでTLS証明書取得 [さくらのVPS/CentOS7]

#-- 変数に必要な値を代入
DOMAIN=masdon.life

#-- certbot のインストール
yum install -y certbot

#-- 80/tcp の port 解放
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --reload

#-- TLS証明書の取得
certbot -n certonly --standalone -d ${DOMAIN} -m admin@${DOMAIN} --agree-tos

#-- 証明書の自動更新設定。更新時に後ほどインストールする nginx と postfix の reload を実行
echo "$((${RANDOM}%60)) $((${RANDOM}%24)) * * $((${RANDOM}%7)) root certbot renew --webroot -w /var/www/html/http_root --post-hook 'systemctl reload nginx postfix'" > /etc/cron.d/certbot-auto

#-- 取得した証明書の確認
ls -l /etc/letsencrypt/live/${DOMAIN}/*pem
lrwxrwxrwx 1 root root 35 12月 29 22:04 /etc/letsencrypt/live/masdon.life/cert.pem -> ../../archive/masdon.life/cert1.pem
lrwxrwxrwx 1 root root 36 12月 29 22:04 /etc/letsencrypt/live/masdon.life/chain.pem -> ../../archive/masdon.life/chain1.pem
lrwxrwxrwx 1 root root 40 12月 29 22:04 /etc/letsencrypt/live/masdon.life/fullchain.pem -> ../../archive/masdon.life/fullchain1.pem
lrwxrwxrwx 1 root root 38 12月 29 22:04 /etc/letsencrypt/live/masdon.life/privkey.pem -> ../../archive/masdon.life/privkey1.pem

02. DNSサーバ構築 – unbound/nsd [さくらのVPS/CentOS7]

・DNSキャッシュサーバの構築

#-- unbound のインストール
yum install -y unbound

#-- unbound の起動
systemctl enable unbound
systemctl start unbound

#-- 再起動で resolv.conf が書き変わらないように設定変更
sed -i '/^\[main\]/a dns=none' /etc/NetworkManager/NetworkManager.conf
systemctl restart NetworkManager

#-- nameserverをunboundを優先して使用するように設定を変更
sed -i "1s/^/nameserver 127.0.0.1\n/" /etc/resolv.conf

・DNSコンテンツサーバの構築

#-- 変数に必要な値を代入
ZONE=masdon.life
IPV4=$(ip addr show eth0 | awk '/inet /{print $2}' | awk -F\/ '{print $1}')
IPV6=$(ip addr show eth0 | awk '/inet6 /&&/global/{print $2}' | awk -F\/ '{print $1}')

#-- nsd のインストールと設定
yum install -y nsd
cp -p /etc/nsd/nsd.conf{,.org}

#- zonefile の参照先を設定
cat <<_EOL_>> /etc/nsd/nsd.conf
zone:
  name: ${ZONE}
  zonefile: zone/${ZONE}.zone
_EOL_

#- global ip での bind を設定
sed -i -e "/^server/a\        ip-address: ${IPV4}"  /etc/nsd/nsd.conf
sed -i -e "/^server/a\        ip-address: ${IPV6}"  /etc/nsd/nsd.conf

#- zonefile を作成(PUBLICKKEYは、DKIMの共通鍵をメールサーバ構築時に入力する)
mkdir -p /etc/nsd/zone
cat <<_EOL_> /etc/nsd/zone/${ZONE}.zone
\$TTL 3600
@                       IN      SOA     ${ZONE}. root.${ZONE}. (
                                $(date +%Y%m%d00)      ; Serial
                                3600            ; Refresh
                                300             ; Retry
                                604800          ; Expire
                                86400           ; Minimum
                                )
@                       IN      NS      ns01.${ZONE}.
                        IN      NS      ns02.${ZONE}.
                        IN      A       ${IPV4}
                        IN      AAAA    ${IPV6}
                        IN      TXT     "v=spf1 +ip4:${IPV4} +ip6:${IPV6} -all"
                        IN      CAA     0 issue "letsencrypt.org"
                        IN      MX 100  ${ZONE}.
_dmarc                  IN      TXT     "v=DMARC1; p=reject; rua=mailto:root@${ZONE}"
_adsp._domainkey        IN      TXT     "dkim=discardable"
;default._domainkey      IN      TXT     "v=DKIM1; k=rsa; p=PUBLICKKEY"
autoconfig              IN      CNAME   ${ZONE}.
ns01                    IN      A       ${IPV4}
ns01                    IN      AAAA    ${IPV6}
ns02                    IN      A       ${IPV4}
ns02                    IN      AAAA    ${IPV6}
vps                     IN      A       ${IPV4}
vps                     IN      AAAA    ${IPV6}
_EOL_

#-- nsd の起動
systemctl enable nsd
systemctl start nsd

#-- 53/tcp,udp の port 解放
firewall-cmd --permanent --add-port=53/{tcp,udp}
firewall-cmd --reload

#-- ipv6 の global ip に疎通があるかを確認するスクリプトを作成
cat <<_EOL_> /usr/local/bin/ipv6upchk.sh
#!/bin/bash

PROC=\$1
IPV6=${IPV6}

for x in \$(seq 1 30)
do
  ping6 -c 1 -W 1 \${IPV6} >/dev/null 2>&1
  if [ $? -eq 0 ]
  then
    echo "\${PROC}: [\${IPV6}] is ready"
    sleep 2
    exit 0
  fi
  sleep 1
done

exit 1
_EOL_

chmod 755 /usr/local/bin/ipv6upchk.sh

#-- OS起動時に ipv6 の global ip に疎通があるかを事前に確認しないとGlobal IP での bind に失敗し nsd が起動してこないことがある為、チェックスクリプト ExecStartPreに登録する
sed -i '/^EnvironmentFile/a ExecStartPre=/usr/local/bin/ipv6upchk.sh nsd' /usr/lib/systemd/system/nsd.service
systemctl daemon-reload

#-- 設定したレコードがdigで引けるか確認する
dig @${IPV4} masdon.life soa +short
masdon.life. root.masdon.life. 2019010601 3600 300 604800 86400

さくらのVPSのコンソールで逆引きに vps.masdon.life を設定する

・お名前ドットコムで該当ドメインのNSの設定を ns0[12].masdon.life に変更する

01. 初期設定 [さくらのVPS/CentOS7]

#-- ホスト名の設定
hostnamectl set-hostname vps.masdon.life

#-- よく使用するパッケージのインストールとアップデート
yum install -y epel-release
yum install -y bind-utils telnet jq expect bash-completion whois knot-utils
yum update -y

#-- sshd の ClientAliveInterval のチューニング
cp -p /etc/ssh/sshd_config{,.org}
sed -i -e 's/#ClientAliveInterval 0/ClientAliveInterval 120/' /etc/ssh/sshd_config

#-- IPv6 の有効化
sed -i -e "s/net.ipv6.conf.all.disable_ipv6.*/net.ipv6.conf.all.disable_ipv6 = 0/" /etc/sysctl.conf
sed -i -e "s/net.ipv6.conf.default.disable_ipv6.*/net.ipv6.conf.default.disable_ipv6 = 0/" /etc/sysctl.conf

sed -i -e "s/^#//g" /etc/sysconfig/network
sed -i -e "s/^#//g" /etc/sysconfig/network-scripts/ifcfg-eth0
sed -i -e "s/^#//g" /etc/resolv.conf

sysctl -p
service network restart

#-- 再起動
reboot
  • ssh key の作成や登録は必要であれば実施する

さくらのVPSにCentOS7でサーバを構築する

さくらのVPSにOSSでDNSやメール、Webサーバを構築する手順

・VPSの構成

メモリCPUDISKOS
1GB仮想 2coreSSD 30GBCentOS7

Swapすることを前提にDISKはSSDを選択。

・ドメイン

お名前ドットコムで取得している masdon.life (近々失効予定) を使用

・ホスト名

vps.masdon.life を設定

・注意

  1. 特に記述がない限り root アカウントで作業をすること
  2. メールサーバの構築は手順の1から11まで数字順に全て実施すること
  3. 記事の全てのサーバの構築には上記スペックでは足りない為、取捨選択するか、より高スペックなVPSを使用すること