various fixes, internal mail server
authorIan Kelling <ian@iankelling.org>
Sun, 5 Feb 2017 04:02:36 +0000 (20:02 -0800)
committerIan Kelling <ian@iankelling.org>
Sun, 5 Feb 2017 04:02:36 +0000 (20:02 -0800)
btrbk-run
distro-begin
distro-end
dynamic-ip-update.sh [new file with mode: 0755]
mail-cert-cron [new file with mode: 0644]
mail-route [new file with mode: 0755]
mail-setup
rootsshsync

index 759b3a4782ae32407c86e5a5e5ba745a589d10f4..e812d5bd6388c4a240730d1cd905cf5be6638676 100755 (executable)
--- a/btrbk-run
+++ b/btrbk-run
@@ -31,12 +31,14 @@ script_dir=$(dirname $(readlink -f "$BASH_SOURCE"))
 conf_only=false
 dry_run=false # mostly for testing
 resume_arg=
+do_i=true
 
-temp=$(getopt -l help hcnprt: "$@") || usage 1
+temp=$(getopt -l help hcinprt: "$@") || usage 1
 eval set -- "$temp"
 while true; do
     case $1 in
         -c) conf_only=true; shift ;;
+        -i) do_i=false; shift ;;
         -n) dry_run=true; dry_run_arg=-n; shift ;;
         -p) progress_arg="--progress"; shift ;;
         # btrbk arg: Resume only. Skips snapshot creation.
@@ -147,14 +149,17 @@ fi
 
 # for i, we just do a 1 way sync from master to backup,
 # and manually manage any changes to that.
-do_i=false
+i_possible=false
 for tg in ${targets[@]}; do
     # for an initial run, btrbk requires the dir to exist
     ssh root@$tg mkdir -p /mnt/root/btrbk
     if [[ $tg == frodo && $HOSTNAME == treetowl ]]; then
-        do_i=true
+        i_possible=true
     fi
 done
+if ! $i_possible; then
+    do_i=false
+fi
 
 
 vol=/mnt/root
index 69bbec775c598ec5e687fb35f95f4e58436aec4a..d2b6e083bbfa2c6093c97ee588c2bca2b8988ccf 100755 (executable)
@@ -612,6 +612,10 @@ Type=oneshot
 ExecStart=/root/imount
 
 [Install]
+# note /kr needs networking, this target is the simplest way to
+# time it when the network should be up, but not do something
+# dumb like delay startup until the network is up. It happens
+# at some time after network.target
 WantedBy=multi-user.target
 EOF
     sudo systemctl daemon-reload # needed if the file was already there
index 22e732683bb1244b7c2dba3f5eb2dc395a0b0fda..a0a6608f667696fe9619943f1b1e4cf7eb039d44 100755 (executable)
@@ -32,7 +32,6 @@ spa() { # simple package add
     simple_packages+=($@)
 }
 
-
 distro=$(distro-name)
 
 pending_reboot=false
@@ -78,6 +77,7 @@ case $HOSTNAME in
             gnome-screenshot
             i3lock
             jq
+            linux-doc
             locate
             manpages
             manpages-dev
@@ -254,6 +254,27 @@ case $HOSTNAME in
         s sed -ri "s/^ *(serverpassword=).*/\1$(< /a/bin/bash_unpublished/mumble_pass)/" /etc/mumble-server.ini
         sgo mumble-server
 
+        vpn-server-setup -d
+
+        sudo dd of=/etc/systemd/system/vpnmail.service <<EOF
+[Unit]
+Description=Turns on iptables mail nat
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/sbin/iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 25 -j DNAT --to-destination 10.8.0.4:25
+ExecStop=/sbin/iptables -t nat -D PREROUTING -i eth0 -p tcp -m tcp --dport 25 -j DNAT --to-destination 10.8.0.4:25
+
+[Install]
+WantedBy=openvpn.service
+EOF
+        ser daemon-reload
+        ser enable vpnmail.service
+        acme-tiny-wrapper mail.iankelling.org
+        sgo openvpn
+
+
         echo "$0: $(date): ending now)"
         exit 0
         ;;
@@ -262,7 +283,15 @@ esac
 
 ########### end section including li/lj ###############
 
-
+if private-host; then
+    vpn-mk-client-cert -n mail li
+    echo "ifconfig-push 10.8.0.4 255.255.255.0" | ssh root@li dd of=/etc/openvpn/client-config/$(openssl x509 -noout -subject -in mail.crt | sed -r 's/.*CN *= *([^,]+).*/\1/')
+fi
+ser enable mailroute
+if [[ $HOSTNAME == treetowl ]]; then
+    # note, this will need to be changed when the mail host changes
+    sgo openvpn-client@mail
+fi
 
 ## android studio setup
 # this contains the setting for android sdk to point to
@@ -276,19 +305,6 @@ lnf /a/opt/.AndroidStudio2.2 ~
 spa lib32stdc++6 default-jdk
 
 
-if [[ $HOSTNAME == frodo ]]; then
-    case $distro in
-        ubunut|debian)
-            pi libsqlite3-dev
-            cd /a/opt/duperemove
-            make clean
-            make
-            s make install
-            ;;
-        #others unknown
-    esac
-fi
-
 case $distro in
     arch) pi syncthing ;;
     ubuntu|debian)
diff --git a/dynamic-ip-update.sh b/dynamic-ip-update.sh
new file mode 100755 (executable)
index 0000000..60c9dd9
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/bash -l
+
+
+# note: in practice, I've not seen my ip address change under comcast
+# for over a year. If the internet hadn't mislead me, I wouldn't have
+# bothered.
+
+
+
+
+# based on: https://www.namecheap.com/support/knowledgebase/article.aspx/36/11/how-do-i-start-using-dynamic-dns
+
+# go to advanced dns, enable the little slider checkbox for dynamic dns,
+# add dnynamic dns records for @ and * (not sure * will work, but eh),
+# with the initial ip you want. remove any other host records, for example
+# the initial default ones. copy the dynamic dns password to /p/dynamic-ip-pass.
+
+# other articles I found usefull previously, but not the last time
+#  http://mwholt.blogspot.com/2013/09/how-to-set-up-dynamic-dns-in-5-minutes.html
+# https://www.namecheap.com/support/knowledgebase/article.aspx/583/11/how-do-i-configure-ddclient
+
+ip=`curl -s4 echoip.com`
+curl -sS "https://dynamicdns.park-your-domain.com/update?host=@&domain=$HOME_DOMAIN&password=$(cat /p/dynamic-ip-pass)&ip=$ip" > /dev/null | /a/exe/log-once dynamic-ip
+
+# an alternative, putting my ip on some known server,
+# allows ssh to home if I can access that server:
+# ssh -o "ProxyCommand ssh someserver -W desktop:22" desktop
+
+# ssh root@some_server bash <<'EOF' | log-once dynamic-ip
+# sed -i --follow-symlinks '/desktop$/d' /etc/hosts
+# echo "${SSH_CLIENT%% *} desktop" >> /etc/hosts
+# EOF
diff --git a/mail-cert-cron b/mail-cert-cron
new file mode 100644 (file)
index 0000000..fd87130
--- /dev/null
@@ -0,0 +1,25 @@
+#!/bin/bash
+# Copyright (C) 2016 Ian Kelling
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+#     http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
+
+source /a/bin/bash_unpublished/source-semi-priv
+if [[ $HOSTNAME == $MAIL_HOST ]]; then
+    local_mx=mail.iankelling.org
+    rsync_common="s rsync -og --chown=root:Debian-exim --chmod=640 root@li:/p/c/machine_specific/li/webservercerts/$local_mx-"
+    ${rsync_common}chained.pem /etc/exim4/exim.crt
+    ${rsync_common}domain.key /etc/exim4/exim.key
+fi
diff --git a/mail-route b/mail-route
new file mode 100755 (executable)
index 0000000..a508e2e
--- /dev/null
@@ -0,0 +1,70 @@
+#!/bin/bash
+# Copyright (C) 2016 Ian Kelling
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+#     http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+[[ $EUID == 0 ]] || exec sudo "$BASH_SOURCE" "$@"
+
+source /a/bin/errhandle/errcatch-function
+source /a/bin/errhandle/errallow-function
+source /a/bin/errhandle/bash-trace-function
+errcatch
+
+usage() {
+    cat <<'EOF'
+Usage: mail-route start|stop|show
+EOF
+    exit $1
+}
+
+if (( $# != 1 )); then
+    usage 1
+fi
+case $1 in
+    start)
+        iptables_op=-A
+        ip_op=add
+        e() { "$@"; }
+        ;;
+    stop)
+        iptables_op=-D
+        ip_op=del
+        e() { "$@" || printf "maybe ok failure: %s\n" "$*"; }
+        ;;
+    show)
+        e() { printf "${0##*/}: %s\n" "$*"; "$@"; }
+        e iptables -t mangle -S
+        e iptables -t nat -S
+        e ip rule
+        e ip route show table 1
+        exit 0
+        ;;
+    *)
+        usage 1
+        ;;
+esac
+
+
+# note, something like this does not work for packets which
+# exim is replying to. I don't know why.
+#iptables -t mangle -A OUTPUT -m owner --uid-owner Debian-exim -j MARK --set-mark 0x1
+
+
+e iptables -t mangle $iptables_op OUTPUT -m tcp -p tcp -m multiport --sports 25 -j MARK --set-mark 0x1
+e iptables -t nat $iptables_op POSTROUTING -o tun0 -m mark --mark 0x1 -j SNAT --to-source 10.8.0.4
+e ip rule $ip_op fwmark 1 table 1
+# note, this rule does not persist when the tun interface is deleted
+e ip route $ip_op default via 10.8.0.1 table 1
+e ip route $ip_op 192.168.1.0/24 via 192.168.1.1 dev br0 table 1
+
+exit 0
index 47d0710096b387b9d24db9c58ff7a5201bd581e1..ede33e482b868671927830f220eea41e737987f6 100755 (executable)
@@ -54,17 +54,20 @@ if ! exim && ! postfix; then
     exit 1
 fi
 
-if private-host; then
+
+local_mx=mail.iankelling.org
+if [[ $HOSTNAME == $MAIL_HOST ]]; then
     host=mail.messagingengine.com
-    forward=$HOSTNAME@$PERSONAL_DOMAIN
+    relayhost="[$host]:587" # postfix
+    smarthost="$host::587" # exim
 else
-    # ses initially suggests port 25, but I had problems connecting to that.
-    host=email-smtp.us-west-2.amazonaws.com
-    forward=$HOSTNAME@$IMPERSONAL_DOMAIN
+    host=$local_mx
+    relayhost="[$host]:25" # postfix
+    smarthost="$host::25" # exim
 fi
 
-relayhost="[$host]:587" # postfix
-smarthost="$host::587" # exim
+forward=ian@$local_mx
+
 
 # background: This also works instead of ~/.forward
 # s sed -i --follow-symlinks '/^root/d' /etc/aliases ||:
@@ -84,7 +87,6 @@ case $distro in
     *) :
 esac
 
-read -r domain pass < <(s cat /etc/mailpass) # format: domain user:pass
 if postfix; then
     # dunno why, but debian installed postfix with builddep emacs
     # but I will just explicitly install it here since
@@ -127,17 +129,21 @@ EOF
     # up and fails. snippet from syslog: type=AAAA: Host not found, try again
 
 
-    # mailpass is just a name i made up, since postfix and
-    # exim both use a slightly crazy format to translate to
-    # each other, it's easier to use my own format.
     f=/etc/postfix/sasl_passwd
+    s rm -f $f
     s touch $f
     s chmod 600 $f
-    printf "[%s]:587 %s" "$domain" "${pass/@/#}" | s dd of=/etc/postfix/sasl_passwd 2>/dev/null
+    s cat /etc/mailpass| while read -r domain port pass; do
+        # format: domain port user:pass
+        # mailpass is just a name i made up, since postfix and
+        # exim both use a slightly crazy format to translate to
+        # each other, it\'s easier to use my own format.
+        printf "[%s]:%s %s" "$domain" "$port" "${pass/@/#}" | s tee -a $f >/dev/null
+    done
     s postmap hash:/etc/postfix/sasl_passwd
     s service postfix reload
 
-else # exim
+else # exim. has debian specific stuff for now
 
     # wording of question from dpkg-reconfigure exim4-config
     # 1. internet site; mail is sent and received directly using SMTP
@@ -145,26 +151,78 @@ else # exim
     # 3. mail sent by smarthost; no local mail
     # 4. local delivery only; not on a network
     # 5. no configuration at this time
+    #
+    # only the one receiving host needs option 2, the rest can do option 1, but
+    # that host might change, so we pick option 2 and later
+    # don't set it up to receive anything. Also, only receiving host needs
+    # dc_other_hostnames and beyond, but no harm.
 
-    # default mailname is $HOSTNAME.lan,
-    # mailname makes addresses like "root" be root@mailname
-    # and a qualified domain does not get forwarded per
-    # .forward. whatever, this fixes that.
+    # note, another related setting is /etc/mailname, which
+    # is set to be $HOSTNAME.lan on stretch. this may need to be
+    # setup on other distros.
+
+    #
     s debconf-set-selections <<EOF
-exim4-config exim4/dc_eximconfig_configtype select mail sent by smarthost; no local mail
+exim4-config exim4/dc_eximconfig_configtype select mail sent by smarthost; received via SMTP or fetchmail
 exim4-config exim4/dc_smarthost string $smarthost
 exim4-config exim4/use_split_config boolean true
-exim4-config exim4/mailname string $HOSTNAME
+exim4-config exim4/dc_other_hostnames string mail.iankelling.org
+exim4-config exim4/dc_postmaster string ian
+exim4-config exim4/dc_localdelivery select Maildir format in home directory
 EOF
+    # debconf settings will not work if packages are already installed,
+    # such as on vps images.
+    pu exim4-daemon-light exim4-daemon-heavy exim4-config exim4-base exim4
     # light version does not have sasl auth support.
     pi exim4-daemon-heavy
 
+    s dd of=/etc/systemd/system/mailcert.service <<'EOF'
+[Unit]
+Description=Mail cert rsync
+After=multi-user.target
+
+[Service]
+Type=oneshot
+ExecStart=/a/bin/log-quiet/sysd-mail-once /a/bin/distro-setup/mail-cert-cron
+EOF
+
+    s dd of=/etc/systemd/system/mailcert.timer <<'EOF'
+[Unit]
+Description=Run mail-cert once a day
+
+[Timer]
+OnCalendar=daily
+
+[Install]
+WantedBy=timers.target
+EOF
+    ser start mailcert
+    sgo mailcert.timer
+
     f=/etc/exim4/passwd.client
+    s rm -f $f
     s touch $f
-    s chmod 640 $f # before writing sensitive info
+    s chmod 640 $f
     s chown root:Debian-exim $f
-    # reference: exim4_passwd_client(5)
-    printf "%s:%s" "$domain" "$pass" | s dd of=$f 2>/dev/null
+    # generating secure pass, and storing for server too:
+    # user=USUALLY_SAME_AS_HOSTNAME
+    # f=$(mktemp)
+    # apg -m 50 -x 70 -n 1 -a 1 -M CLN >$f
+    # echo "$user:$(mkpasswd -m sha-512 -s <$f)" >>/p/c/filesystem/etc/exim4/passwd
+    # echo "mail.iankelling.org:$user:$(<$f)" >> /p/c/machine_specific/$user/filesystem/etc/mailpass
+    #
+    # for ad-hoc testing of some random new host:
+    # host=testhost # client host username & hostname
+    # f=$(mktemp)
+    # apg -m 50 -x 70 -n 1 -a 1 -M CLN >$f
+    # s sed "/^host:/d" /etc/exim4/passwd
+    # echo "$host:$(mkpasswd -m sha-512 -s <$f)" | s tee -a /etc/exim4/passwd
+    # echo "mail.iankelling.org:$host:$(<$f)" | ssh root@$host dd of=/etc/exim4/passwd.client
+    s cat /etc/mailpass| while read -r domain port pass; do
+        # reference: exim4_passwd_client(5)
+        printf "%s:%s" "$domain" "$pass" | s tee -a $f >/dev/null
+    done
+
     # https://blog.dhampir.no/content/make-exim4-on-debian-respect-forward-and-etcaliases-when-using-a-smarthost
     # i only need .forwards, so just doing that one.
     cd /etc/exim4/conf.d/router
@@ -174,12 +232,14 @@ EOF
     of=175_$b
     # sed to make the router name unique
     sed -r s/^\\S+:/$b:/ 600_exim4-config_$a | s dd of=$tmp 2>/dev/null
-    if ! diff -q >/dev/null $tmp $of; then
+    if ! diff -q $tmp $of &>/dev/null; then
         s dd if=$tmp of=$of >/dev/null
         ser restart exim4
     fi
 fi
 
+
+
 # linode image has a root alias. completely useless, remove it.
 sudo sed -i '/^root:/d' /etc/aliases
 
index baf42967acf4e465b0752a46f454d2422550afbc..ebfc80216b6e293e9162e5c2f3ec825048f166ad 100755 (executable)
 set -eE -o pipefail
 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
 
-if sudo test -e /q/root/.ssh; then
-    sudo /a/exe/lnf /q/root/.ssh /root
+[[ $EUID == 0 ]] || exec sudo "$BASH_SOURCE" "$@"
+
+if test -e /q/root/.ssh; then
+    export LNF_VERBOSE=true
+    if ! /a/exe/lnf /q/root/.ssh /root > /tmp/lnf_log; then
+        cat /tmp/lnf_log
+    fi
 else
-    sudo mkdir -p /root/.ssh
-    sudo chmod 700 /root/.ssh
+    mkdir -p /root/.ssh
+    chmod 700 /root/.ssh
 fi
-sudo cp -rL $(eval echo ~${SUDO_USER:-$USER})/.ssh/* /root/.ssh
-sudo chown -R root:root /root/.ssh
+cp -rL $(eval echo ~${SUDO_USER:-$USER})/.ssh/* /root/.ssh
+chown -R root:root /root/.ssh