Merge branch 'dev' of feistymeow.org:feisty_meow into dev
[feisty_meow.git] / scripts / system / add_domain.sh
1 #!/bin/bash
2
3 # this set of functions serve the main purpose of adding new domains or subdomains to the bind9 DNS server on the current host.
4 # it is currently highly specific to running a bunch of domains on a linux VM, where the VM has one IP address.
5 # note that bind 'named' must already be configured.
6 # also, it is assumed that if a subdomain is being added, then the containing domain has already been configured and is 
7 # configured in a file similar to "blah.com.conf" in /etc/bind.
8 #
9 # Author: Chris Koeritz
10
11 export WORKDIR="$( \cd "$(\dirname "$0")" && \pwd )"  # obtain the script's working directory.
12 export FEISTY_MEOW_APEX="$( \cd "$WORKDIR/../.." && \pwd )"
13
14 source "$FEISTY_MEOW_APEX/scripts/core/launch_feisty_meow.sh"
15
16 # some defaults that are convenient for current purposes.
17 # existing values will be respected over our defaults.
18
19 if [ -z "$IP_ADDRESS" ]; then
20   # in our scheme, the single IP address that all our domains map to.
21   IP_ADDRESS="10.28.42.20"
22 fi
23 if [ -z "$SERVER_ADMIN" ]; then
24   # the email address (where first dot is replaced by @) for the administrator of the domain.
25   SERVER_ADMIN="developer.cakelampvm.com"
26 fi
27 if [ -z "$MAIN_NAME_SERVER" ]; then
28   # the name of the name server for the new domains (should already be configured).
29   MAIN_NAME_SERVER="ns.cakelampvm.com"
30 fi
31 if [ -z "$MAIL_SERVER" ]; then
32   # the name of the mail server for a new domain (should already be configured).
33   MAIL_SERVER="mail.cakelampvm.com"
34 fi
35 if [ -z "$DISTRO" ]; then
36   # the distribution name to be listed in info for the new domain or subdomain.
37   DISTRO="ubuntu"
38 fi
39
40 # creates a totally new domain config file for DNS.
41 function write_new_domain_file()
42 {
43   local domain_name="$1"; shift
44
45   local domain_file="/etc/bind/${domain_name}.conf"
46
47   echo "adding a totally new domain called $domain_name"
48   echo "using the config file: $domain_file"
49
50   if [ -f $domain_file ]; then
51     echo
52     echo "The domain configuration file already exists at:"
53     echo "  $domain_file"
54     echo "Since we don't want to tear that down if it has specialized configuration"
55     echo "data in it, we will just leave it in place and consider our job done."
56     echo
57     exit 0
58   fi
59
60   echo "
61 \$TTL 1W
62 @       IN SOA  @       ${SERVER_ADMIN}. (
63                 2017100801 ; serial
64                 2H ; refresh
65                 8M ; retry
66                 14D ; expiry
67                 6H ) ; minimum
68
69         IN NS           ${MAIN_NAME_SERVER}.
70         IN MX   10      ${MAIL_SERVER}.
71
72 ${domain_name}. IN A    ${IP_ADDRESS}
73         IN HINFO        \"linux server\" \"${DISTRO}\"
74 " >"$domain_file"
75
76   # our personalized configuration approach wants the real owner to own the file.
77   chown "$(logname):$(logname)" $domain_file
78   test_or_die "setting ownership on: $domain_file"
79 }
80
81 # hooks up a new config file into bind's list of zones.
82 function add_zone_for_new_domain()
83 {
84   local domain_name="$1"; shift
85
86   local domain_file="/etc/bind/${domain_name}.conf"
87
88   echo "adding a new domain configured by ${domain_file} into"
89   echo "the named.conf.local configuration file."
90
91   # append the reference to the new conf file in the zone list.
92   echo "
93 zone \"${domain_name}\" in {
94         file \"${domain_file}\";
95         type master;
96         allow-query { any; };
97 };
98
99 ////////////////////////////////////////////////////////////////////////////
100
101 " >> /etc/bind/named.conf.local
102
103   # keep ownership for the real user.
104   chown "$(logname):$(logname)" /etc/bind/named.conf.local
105   test_or_die "setting ownership on: /etc/bind/named.conf.local"
106
107 }
108
109 # adds a new subdomain under a containing domain.
110 function add_new_subdomain()
111 {
112   local new_domain="$1"; shift
113
114   # split up the full domain name into subdomain portion and containing domain.
115   local subdomain="${new_domain%.*.*}"
116   local containing_domain="${new_domain#*.}"
117
118   echo "adding a subdomain $subdomain to containing domain $containing_domain"
119
120   local domain_file="/etc/bind/${containing_domain}.conf"
121   # see if config file already exists; if not, complain.
122   if [ ! -f "$domain_file" ]; then
123     echo "The domain configuration file for $new_domain is missing."
124     echo "It should already be present in: $domain_file"
125     echo "Please add the containing domain before trying to add a subdomain."
126     exit 1
127   fi
128
129   # see if subdomain already present in config.
130   if [ $(grep -q "$new_domain" "$domain_file") ]; then
131     echo "The subdomain $subdomain already seems to exist in the domain"
132     echo "configuration file: $domain_file"
133     echo "Please edit the config file to remove the subdomain before trying"
134     echo "to re-add the subdomain."
135     exit 1
136   fi
137
138   # append the new subdomain into the config file.
139   echo "
140 ${subdomain}.${containing_domain}.    IN A    ${IP_ADDRESS}
141         IN HINFO \"linux server\" \"${DISTRO}\"
142 " >> /etc/bind/${containing_domain}.conf
143
144   # keep ownership for real user.
145   chown "$(logname):$(logname)" "/etc/bind/${containing_domain}.conf"
146   test_or_die "setting ownership on: /etc/bind/${containing_domain}.conf"
147 }
148
149 function restart_bind()
150 {
151   echo restarting DNS server.
152   service bind9 restart
153   if [ $? -ne 0 ]; then
154     echo "The bind service did not restart properly.  Please check the error logs."
155     exit 1
156   fi
157   echo DNS server restarted.
158 }
159
160 # main body of script.
161
162 if [[ $EUID != 0 ]]; then
163   echo "This script must be run as root or sudo."
164   exit 1
165 fi
166
167 new_domain="$1"; shift
168
169 if [ -z "$new_domain" ]; then
170   echo "This script needs a domain name to add to DNS." 
171   exit 1
172 fi
173
174 # if domain name has three or more components, then add a subdomain.
175 # otherwise, add a full new domain.
176 if [[ $new_domain == *"."*"."* ]]; then
177   # add a subdomain to the containing domain.
178   add_new_subdomain "$new_domain"
179   restart_bind
180 else
181   # create a totally new domain in DNS.
182   write_new_domain_file "$new_domain"
183   add_zone_for_new_domain "$new_domain"
184   restart_bind
185 fi
186
187