├── LICENSE
├── README.md
└── jss-in-a-box.sh
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Richard Purves
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JSS-In-A-Box
2 |
3 | ## The (almost) complete Jamf Pro JSS setup script
4 | ## http://www.richard-purves.com/?p=136
5 |
6 | ## Before we start, i'm planning to refactor the code and modularise a lot more functions as it's getting untidy in here. That'll be next big release, just not sure when.
7 |
8 | ### Introduction
9 |
10 | This is the (almost) complete setup script for JAMF Software's JSS server. It will perform the following tasks :-
11 |
12 | 1. Install and configure all the software packages required to run the JSS
13 | 2. Harden the server via software firewall and optional HTTPS certificates
14 | 3. Show all currently running JSS on the server
15 | 4. Create a new JSS and Database
16 | 5. Delete an existing JSS and Database
17 | 6. Dump a selected (or ALL) JSS database to a file
18 | 7. Upload a database file back into MySQL
19 | 8. Upgrade a single JSS install on the server
20 | 9. Upgrade ALL JSS installs on the server
21 | 10. (optional) Refresh Tomcat SSL certificate from [LetsEncrypt](http://letsencrypt.org)
22 | (The LetsEncrypt certificates are automatically renewed via a cron job. The same code can be invoked manually with this option)
23 | 11. Will now optimally configure Tomcat and MySQL (locally only) for number of instances, available ram etc etc.
24 | (this one was HARD to do)
25 |
26 | The only things it doesn't do are:
27 | 1) Set up anything to do with load balancing. That can be done inside the JSS itself.
28 | 2) Any remote server configuration with the sole exception of modifying remote databases.
29 | 3) Clustered server setup.
30 |
31 | ###### Oh, and NO SNEAKY using this on your CJA course! I've tipped off the JAMF instructors I know of!
32 |
33 | ### Getting started
34 |
35 | This assumes you have an either an Ubuntu 16.04 LTS or a RedHat 7.x server installed with openssh.
36 | This also assumes the server is properly configured to see the internet and has a properly set up DNS hostname.
37 |
38 | Please do NOT use Ubuntu's minimal iso install. This will miss out lots of key software and this script will fail. Use the "server" download instead.
39 |
40 | 1. Download the proper script depending on which Linux distribution you are using.
41 | 2. Edit the jss-in-a-box.sh script variables in line with your own security policies
42 | - Server admin username
43 | - Use LetsEncrypt (if this is set to FALSE, then the JSS will be set up without HTTPS)
44 | - SSL Domain name for the server
45 | - SSL E-mail address to register with the LetsEncrypt CA
46 | - SSL Keypass password
47 | - MySQL root password
48 | - MySQL server address
49 | - JSS database username
50 | - JSS database password
51 | 3. Edit the jss-in-a-box.sh script firewall settings.
52 | 4. scp the ROOT.war file supplied by JAMF to the server
53 | 5. scp the jss-in-a-box.sh script over to the server
54 | 6. Run the script with sudo. e.g. sudo ./jss-in-a-box.sh
55 | 7. Follow the options! (They are all disabled until no.1 is run successfully).
56 |
57 | You should, depending on server and internet speed have a fully functioning JSS running inside of an hour. Probably less.
58 |
59 | (Optional) Run the script with sudo ./jss-in-a-box.sh -h to get a help prompt.
60 |
61 | The instructional video below provides more details of operation. NOTE: This is of an earlier version but the info is still valid.
62 |
63 | ### Instructional Video
64 |
65 |
66 |
67 | ### Software Installed
68 |
69 | * JSS
70 | * Curl (missing from Ubuntu)
71 | * Git (used purely for installing LetsEncrypt)
72 | * Unzip
73 | * Uncomplicated Firewall (Ubuntu) / FirewallD (Redhat)
74 | * OpenSSL
75 | * OpenVMTools
76 | * Oracle Java 8
77 | * Java Cryptography Extensions
78 | * Apache Tomcat 8.0x
79 | * MySQL Server 5.7
80 | * (optional) LetsEncrypt
81 |
--------------------------------------------------------------------------------
/jss-in-a-box.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ##########################################################################################
4 | #
5 | # JSS in a Box
6 | # (aka a script to initialise, create, configure and delete JSS instances on a Ubuntu/RedHat server.)
7 | # (with apologies to Tom Bridge and https://github.com/tbridge/munki-in-a-box)
8 | #
9 | # The MIT License (MIT)
10 | # Copyright (c) 2015
11 | #
12 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this
13 | # software and associated documentation files (the "Software"), to deal in the Software
14 | # without restriction, including without limitation the rights to use, copy, modify,
15 | # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
16 | # persons to whom the Software is furnished to do so, subject to the following conditions:
17 | #
18 | # The above copyright notice and this permission notice shall be included in all copies or
19 | # substantial portions of the Software.
20 | #
21 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
22 | # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
23 | # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
24 | # FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 | # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | #
27 | ##########################################################################################
28 |
29 | # Author : Richard Purves
30 |
31 | # Version 0.1 - 27th December 2015 - Initial Version
32 | # Version 0.2 - 28th December 2015 - Completed structure and initialisation code
33 | # Version 0.3 - 29th December 2015 - Completed all functions excluding database restoration
34 | # Version 0.4 - 30th December 2015 - Interactive Mode complete. Code for SSL present but untested.
35 | # Version 0.5 - 31st December 2015 - Implemented Ubuntu UFW rules for security
36 | # Implemented ability to talk to an external MySQL server.
37 | # Now creates/deletes JSS log files with modification to the JSS log4j file
38 | # Version 0.6 - 31st December 2015 - Extracts the DataBase.xml file from the provided ROOT.war file
39 | # Version 0.7 - 1st January 2016 - Code simplification and clean up. Was getting messy.
40 | # Can be invoked by parameter and skip the opening menu for specific functions.
41 | # Version 0.8 - 1st January 2016 - HTTPS SSL code implemented and working. Usually. There's all sorts of things out of my control that go wrong with this :(
42 | # Version 0.9 - 2nd January 2016 - Added menu option for SSL certificate update. Checks to see if server.xml is backed up before working on it.
43 | # - Tomcat set to use a max of 3Gb of server memory.
44 | # - cron job created to run an SSL cert refresh every month.
45 | # - This is due to LE's cert lifetime of 90 days and cron's inability to run past daily, monthly or yearly.
46 | # Version 1.0 - 4th January 2016 - RELEASE - LetsEncrypt is now an optional install. Log files repointed on JSS upgrades too.
47 | # - Cleaned up Tomcat caching issues with deleted instances.
48 | # Version 1.0 - 31st March 2016 - Redhat compatible version. No new features so not a version increment.
49 | # Version 1.1 - 12th April 2016 - Update of SSL cipher list to bring into line with https://jamfnation.jamfsoftware.com/article.html?id=384
50 | # Version 2.0 - 14th April 2016 - Merged both scripts together. Now one big universal version with better OS checking.
51 | # Version 2.1 - 16th April 2016 - Now manages Tomcat, MySQL and Java memory settings. Calculated per current formulas on JAMF's CJA course.
52 | # Version 2.2 - 18th April 2016 - Optional redirection of HTTPS traffic to port 443 from 8443 via firewall rules.
53 | # Version 2.3 - 21st April 2016 - Tomcat really doesn't like running with less than 1Gb ram, so we check for 1.5Gb available. Quit if not available.
54 | # Version 2.4 - 22nd April 2016 - Choice of which supported Java version to install. In variable below.
55 | # Version 2.5 - 15th June 2016 - Fixed missing rule in UFW configuration. Also fixed bug where connector keystore file isn't set properly.
56 | # Version 2.6 - 23rd June 2016 - Recoded large chunks of the LetsEncrypt code due to them suddenly getting distribution via repo AND changing the name of the binary that does the work.
57 | # Version 2.7 - 14th July 2016 - Added code to make sure that tomcat webapp folders have correct ownership of the appropriate tomcat user.
58 | # Version 3.0 - 4th August 2016 - Removed Java 7, upgraded Tomcat to version 8. Refactored all the relevant code and paths to compensate for manual install. Down 300+ lines for same functionality!
59 | # Version 3.1 - 6th August 2016 - Cleaned up some embarrassing typos and code swapping to do with LetsEncrypt. Also some interesting Tomcat 8 server.xml changes.
60 | # Big thanks to Cody Butcher for his help on this!
61 | # Version 3.2 - 17th February 2017 - Fixed some pesky mysql error redirection stuff. Won't be prompted for insecure command line anymore!
62 | # Fixed some very annoying tomcat webapp folder ownership stuff that never worked properly. Apparently.
63 | # Version 3.3 - 23rd February 2017 - Brought the Tomcat HTTPS connector settings into line with Jamf's current documentation.
64 | # Version 3.5 - 23rd February 2017 - Major update to use Ubuntu 16.04 LTS in place of 14.04 LTS. Java now uses OpenJDK 8 on both OS. Tomcat has a unified systemd launcher. Code simplified.
65 | # Big thanks to Rich Trouton for quickly helping me with the systemd testing today!
66 | # Version 4.0 - 21st March 2017 - Change MySQL to install 5.7.14 or better with the release of JSS 9.98. Please note new password complexity requirements for db's!
67 | # - Also fixed DUMB deltarpm bug. Removed MaxPermGen setting for Tomcat as Java 8 doesn't support it. Replaced with MetaspaceSize stuff.
68 | # - Replaced LetsEncrypt crontab with a systemd job. OpenJDK replaced with Oracle for BOTH OS platforms due to CPU hammering issues.
69 | # Version 4.1 - 27th March 2017 - Whoops, forgot to clean up a file. Thrown in some extra commands for db integrity checking post upload of database dump file.
70 | # - DB check code thanks to Neil Martin: https://soundmacguy.wordpress.com/2017/03/27/jamf-pro-9-98-on-windows-migrating-to-mysql-5-7/
71 | # Version 4.2 - 9th May 2017 - Fixed LetsEncrypt bug caused by deleting the wrong line in Tomcat server.xml file
72 | # Version 4.3 - 17th May 2017 - Fixed code for new instance creation. Some of the variables were pointing to non-existant file paths. I do wonder what I was thinking at the time. Let's see if people read this.
73 | # Version 4.4 - 19th May 2017 - Sole change to disable password complexity rules on MySQL 5.7
74 | # Version 4.5 - 22nd June 2017 - Fixed bug with HTTPS config for tomcat. Was missing a closing bracket!
75 | # Version 4.6 - 3rd August 2017 - Updated tomcat config due to new jamf security paper: https://resources.jamf.com/documents/white-papers/Securing-Your-Jamf-Server.pdf
76 | # - Corrected very old systemd config bug with LetsEncrypt cert renewal timers.
77 | # Version 4.7 - 7th August 2017 - It was pointed out to me that if Tomcat crashes, it would not auto restart. Fixed SystemD config to compensate. Also fixed shutdown and some RedHat java bugs.
78 | # Version 4.8 - 16th August 2017 - Seems deleting instances wasn't cleaning out the Tomcat work folders properly. Fixed.
79 |
80 | # Set up variables to be used here
81 |
82 | # These variables are user modifiable. Don't forget to configure firewall settings from Line 737!
83 |
84 | export useract="richardpurves" # Server admin username. Used for home location.
85 |
86 | export letsencrypt="FALSE" # Set this to TRUE if you are going to use LetsEncrypt as your HTTPS Certificate Authority.
87 | export sslTESTMODE="TRUE" # Set this to FALSE when you're confident it's generating proper certs for you
88 | export httpsredirect="FALSE" # Set this to TRUE if you want your JSS to appear to be on port 443 using HTTPS
89 | export ssldomain="jssinabox.domain.com" # Domain name for the SSL certificates
90 | export sslemail="richard at richard-purves.com" # E-mail address for the SSL CA
91 | export sslkeypass="changeit" # Password to the keystore. Default is "changeit". Please change it!
92 |
93 | export mysqluser="root" # MySQL root account
94 | export mysqlpw="Changeit1!" # MySQL root account password. Please change it and note security requirements below:
95 | # At least one upper case letter, one lower case letter,
96 | # one digit, and one special character
97 | # and a minimum length of at least 8 characters.
98 | export mysqlserveraddress="localhost" # IP/Hostname of MySQL server. Default is local server.
99 |
100 | export dbuser="jamfsoftware" # Database username for JSS
101 | export dbpass="Changeit1!" # Database password for JSS. Default is "changeit". Please change it and see MySQL restrictions above.
102 |
103 | # These variables should not be tampered with or script functionality will be affected!
104 |
105 | currentdir=$( pwd )
106 | currentver="4.8"
107 | currentverdate="16th August 2017"
108 |
109 | export homefolder="/home/$useract" # Home folder base path
110 | export rootwarloc="$homefolder" # Location of where you put the ROOT.war file
111 | export logfiles="/var/log/JSS" # Location of ROOT and instance JSS log files
112 |
113 | export tomcatloc="/opt/tomcat8" # Tomcat's installation path
114 | export webapploc="$tomcatloc/webapps" # Tomcat web application install path
115 | export cacheloc="$tomcatloc/work/Catalina/localhost" # Tomcat's webapp cache folder
116 | export user="tomcat" # User and Group used for tomcat
117 | export sslkeystorepath="$tomcatloc/keystore" # Keystore path
118 | export server="$tomcatloc/conf/server.xml" # Tomcat server.xml path
119 |
120 | export ubmycnfloc="/etc/mysql/my.cnf" # MySQL's configuration file path(s)
121 | export rhmycnfloc="/etc/my.cnf"
122 |
123 | export DataBaseLoc="WEB-INF/xml" # DataBase.xml location inside the JSS webapp
124 | export DataBaseXML="$rootwarloc/DataBase.xml.original" # Location of the tmp DataBase.xml file we use for reference
125 |
126 | export lepath="/etc/letsencrypt/live" # LetsEncrypt's certificate storage location
127 |
128 | # All functions to be set up here
129 |
130 | WhichDistAmI()
131 | {
132 | # First check is for Ubuntu 14.04 LTS
133 | if [ -f "/usr/bin/lsb_release" ];
134 | then
135 | ubuntuVersion=`lsb_release -s -d`
136 |
137 | case $ubuntuVersion in
138 | *"Ubuntu 16.04"*)
139 | OS="Ubuntu"
140 | export OS
141 | ;;
142 |
143 | *)
144 | echo -e "Script requires Ubuntu 16.04 LTS. Exiting."
145 | exit 1
146 | ;;
147 | esac
148 | fi
149 |
150 | # Second check is for RedHat 7.x
151 | if [ -f "/etc/redhat-release" ];
152 | then
153 | version=$( cat /etc/redhat-release | awk '{ print $7 }' | cut -c 1 )
154 |
155 | # Is this RedHat 7 server?
156 | if [[ $version != "7" ]];
157 | then
158 | echo -e "Script requires RedHat 7.x. Exiting."
159 | exit 1
160 | else
161 | echo -e "Redhat 7 detected. Proceeding."
162 | OS="RedHat"
163 | export OS
164 | fi
165 | fi
166 |
167 | # Last check is to see if we got a bite or not
168 | if [[ $OS != "Ubuntu" && $OS != "RedHat" ]];
169 | then
170 | echo -e "Script requires either Ubuntu 16.04 LTS or RHEL 7.x. Exiting."
171 | exit 1
172 | fi
173 | }
174 |
175 | AmIroot()
176 | {
177 | # Check for root, quit if not present with a warning.
178 | if [[ "$(id -u)" != "0" ]];
179 | then
180 | echo -e "Script needs to be run as root."
181 | exit 1
182 | else
183 | echo -e "Script running as root. Proceeding."
184 | fi
185 | }
186 |
187 | IsROOTwarPresent()
188 | {
189 | # Check for presence of ROOT.war file or we can't upgrade at all!
190 | if [ ! -f "$rootwarloc/ROOT.war" ];
191 | then
192 | echo -e "\nMissing ROOT.war file from path: $rootwarloc \nPlease copy file to location and try again."
193 | exit 1
194 | else
195 | echo -e "\nROOT.war present at path: $rootwarloc. Proceeding."
196 | fi
197 | }
198 |
199 | TomcatService()
200 | {
201 | systemctl $1 tomcat
202 | }
203 |
204 | MySQLService()
205 | {
206 | if [[ $OS = "Ubuntu" ]];
207 | then
208 | systemctl $1 mysql
209 | fi
210 |
211 | if [[ $OS = "RedHat" ]];
212 | then
213 | systemctl $1 mysqld
214 | fi
215 | }
216 |
217 | CheckMySQL()
218 | {
219 | if [[ $OS = "Ubuntu" ]];
220 | then
221 | export mysql=$(dpkg -l | grep "mysql-server" >/dev/null && echo "yes" || echo "no")
222 | fi
223 |
224 | if [[ $OS = "RedHat" ]];
225 | then
226 | export mysql=$(yum -q list installed mysql-community-server &>/dev/null && echo "yes" || echo "no")
227 | fi
228 | }
229 |
230 | InstanceList()
231 | {
232 | # Is Tomcat present?
233 | [ -d "$tomcatloc" ] && tomcat="yes" || tomcat="no"
234 |
235 | if [[ $tomcat = "no" ]];
236 | then
237 | echo -e "\nTomcat 8 not present. Please install before trying again."
238 | else
239 | echo -e "\nJSS Instance List\n-----------------\n"
240 | find $tomcatloc/webapps/* -maxdepth 0 -type d 2>/dev/null | sed -r 's/^.+\///'
241 | fi
242 | }
243 |
244 | SetupTomcatUser()
245 | {
246 | export user="tomcat"
247 | }
248 |
249 | SetupLogs()
250 | {
251 | # Check and create the JSS log file folder if missing with appropriate permissions.
252 | if [ ! -d $logfiles ];
253 | then
254 | mkdir $logfiles
255 | SetupTomcatUser
256 | chown -R $user:$user $logfiles
257 | fi
258 | }
259 |
260 | UpdatePkgMgr()
261 | {
262 | if [[ $OS = "Ubuntu" ]];
263 | then
264 | echo -e "\nUpdating apt-get repository ...\n"
265 | apt-get update -q
266 |
267 | echo -e "\nUpgrading installed packages ...\n"
268 | apt-get upgrade -q -y
269 | fi
270 |
271 | if [[ $OS = "RedHat" ]];
272 | then
273 |
274 | # Is the delta RPM module installed?
275 | deltarpm=$(yum -q list installed deltarpm &>/dev/null && echo "yes" || echo "no")
276 |
277 | if [[ $deltarpm = "no" ]];
278 | then
279 | echo -e "\nInstalling Delta RPM functionality\n"
280 | yum -q -y install deltarpm
281 | else
282 | echo -e "\nDelta RPM already present. Proceeding."
283 | fi
284 |
285 | echo -e "\nUpdating yum repository ...\n"
286 | yum -q -y update
287 | fi
288 | }
289 |
290 | InstallGit()
291 | {
292 | if [[ $OS = "Ubuntu" ]];
293 | then
294 | # Is git present?
295 | git=$(dpkg -l | grep -w "git" >/dev/null && echo "yes" || echo "no")
296 |
297 | if [[ $git = "no" ]];
298 | then
299 | echo -e "\ngit not present. Installing\n"
300 | apt-get install -q -y git
301 | else
302 | echo -e "\ngit already present. Proceeding."
303 | fi
304 | fi
305 |
306 | if [[ $OS = "RedHat" ]];
307 | then
308 | # Is git present?
309 | git=$(yum -q list installed git &>/dev/null && echo "yes" || echo "no" )
310 |
311 | if [[ $git = "no" ]];
312 | then
313 | echo -e "\ngit not present. Installing."
314 | yum -q -y install git
315 | else
316 | echo -e "\ngit already present. Proceeding."
317 | fi
318 | fi
319 | }
320 |
321 | InstallCurl()
322 | {
323 | if [[ $OS = "Ubuntu" ]];
324 | then
325 | # Is curl present?
326 | git=$(dpkg -l | grep -w "curl" >/dev/null && echo "yes" || echo "no")
327 |
328 | if [[ $git = "no" ]];
329 | then
330 | echo -e "\ncurl not present. Installing\n"
331 | apt-get install -q -y curl
332 | else
333 | echo -e "\ncurl already present. Proceeding."
334 | fi
335 | fi
336 |
337 | if [[ $OS = "RedHat" ]];
338 | then
339 | # Is wget present?
340 | wget=$(yum -q list installed curl &>/dev/null && echo "yes" || echo "no" )
341 |
342 | if [[ $wget = "no" ]];
343 | then
344 | echo -e "\nwcurl not present. Installing."
345 | yum -q -y install curl
346 | else
347 | echo -e "\ncurl already present. Proceeding."
348 | fi
349 | fi
350 | }
351 |
352 | InstallWget()
353 | {
354 | if [[ $OS = "Ubuntu" ]];
355 | then
356 | # Is wget present?
357 | git=$(dpkg -l | grep -w "wget" >/dev/null && echo "yes" || echo "no")
358 |
359 | if [[ $git = "no" ]];
360 | then
361 | echo -e "\nwget not present. Installing\n"
362 | apt-get install -q -y wget
363 | else
364 | echo -e "\nwget already present. Proceeding."
365 | fi
366 | fi
367 |
368 | if [[ $OS = "RedHat" ]];
369 | then
370 | # Is wget present?
371 | wget=$(yum -q list installed wget &>/dev/null && echo "yes" || echo "no" )
372 |
373 | if [[ $wget = "no" ]];
374 | then
375 | echo -e "\nwget not present. Installing."
376 | yum -q -y install wget
377 | else
378 | echo -e "\nwget already present. Proceeding."
379 | fi
380 | fi
381 | }
382 |
383 | InstallUnzip()
384 | {
385 | if [[ $OS = "Ubuntu" ]];
386 | then
387 | # Is unzip installed?
388 | unzip=$(dpkg -l | grep -w "unzip" >/dev/null && echo "yes" || echo "no")
389 |
390 | if [[ $unzip = "no" ]];
391 | then
392 | echo -e "\nunzip not present. Installing\n"
393 | apt-get install -q -y unzip
394 | else
395 | echo -e "\nunzip already present. Proceeding."
396 | fi
397 | fi
398 |
399 | if [[ $OS = "RedHat" ]];
400 | then
401 | # Is unzip installed?
402 | unzip=$(yum -q list installed unzip &>/dev/null && echo "yes" || echo "no" )
403 |
404 | if [[ $unzip = "no" ]];
405 | then
406 | echo -e "\nunzip not present. Installing\n"
407 | yum -q -y install unzip
408 | else
409 | echo -e "\nunzip already present. Proceeding."
410 | fi
411 | fi
412 | }
413 |
414 | PrepDBfile()
415 | {
416 | # Is unzip installed? Check by calling the unzip function.
417 | InstallUnzip
418 |
419 | # Check for presence of DataBase.xml.original file.
420 | # If missing, extract the DataBase.xml and place it in the $rootwarloc directory
421 | # Rename to DataBase.xml.original
422 | if [ ! -f "$rootwarloc/DataBase.xml.original" ];
423 | then
424 | echo -e "\nExtracting DataBase.xml from ROOT.war\n"
425 | unzip -j $rootwarloc/ROOT.war "WEB-INF/xml/DataBase.xml" -d $rootwarloc
426 | mv $rootwarloc/DataBase.xml $rootwarloc/DataBase.xml.original
427 | else
428 | echo -e "\nDataBase.xml.original found at path: $rootwarloc. Proceeding."
429 | fi
430 | }
431 |
432 | InstallFirewall()
433 | {
434 | if [[ $OS = "Ubuntu" ]];
435 | then
436 | # Is UFW present?
437 | ufw=$(dpkg -l | grep "ufw" >/dev/null && echo "yes" || echo "no")
438 |
439 | if [[ $ufw = "no" ]];
440 | then
441 | echo -e "\nufw not present. Installing.\n"
442 | apt-get install -q -y ufw
443 | else
444 | echo -e "\nufw already installed. Proceeding."
445 | fi
446 | fi
447 |
448 | if [[ $OS = "RedHat" ]];
449 | then
450 | # Is firewalld installed?
451 | fwd=$(yum -q list installed firewalld &>/dev/null && echo "yes" || echo "no" )
452 |
453 | if [[ $fwd = "no" ]];
454 | then
455 | echo -e "\nFirewallD not present. Installing."
456 | yum -q -y install firewalld
457 | else
458 | echo -e "\nFirewallD already installed. Proceeding."
459 | fi
460 | fi
461 | }
462 |
463 | InstallOpenSSH()
464 | {
465 | if [[ $OS = "Ubuntu" ]];
466 | then
467 | # Is OpenSSH present?
468 | openssh=$(dpkg -l | grep "openssh" >/dev/null && echo "yes" || echo "no")
469 |
470 | if [[ $openssh = "no" ]];
471 | then
472 | echo -e "\nopenssh not present. Installing.\n"
473 | apt-get install -q -y openssh
474 | else
475 | echo -e "\nopenssh already installed. Proceeding."
476 | fi
477 | fi
478 |
479 | if [[ $OS = "RedHat" ]];
480 | then
481 | # Is OpenSSH present?
482 | openssh=$(yum -q list installed openssh &>/dev/null && echo "yes" || echo "no" )
483 |
484 | if [[ $openssh = "no" ]];
485 | then
486 | echo -e "\nopenssh not present. Installing.\n"
487 | yum -q -y install openssh
488 | else
489 | echo -e "\nopenssh already installed. Proceeding."
490 | fi
491 | fi
492 | }
493 |
494 | InstallOpenVMTools()
495 | {
496 | if [[ $OS = "Ubuntu" ]];
497 | then
498 | # Are the open-vm-tools present?
499 | openvmtools=$(dpkg -l | grep "open-vm-tools" >/dev/null && echo "yes" || echo "no")
500 |
501 | if [[ $openvmtools = "no" ]];
502 | then
503 | echo -e "\nopen vm tools not present. Installing."
504 |
505 | echo -e "\nGetting VMware packaging keys from server."
506 | wget http://packages.vmware.com/tools/keys/VMWARE-PACKAGING-GPG-DSA-KEY.pub
507 | wget http://packages.vmware.com/tools/keys/VMWARE-PACKAGING-GPG-RSA-KEY.pub
508 |
509 | echo -e "\nInstalling VMware packaging keys into apt."
510 | apt-key add ./VMWARE-PACKAGING-GPG-DSA-KEY.pub
511 | apt-key add ./VMWARE-PACKAGING-GPG-RSA-KEY.pub
512 |
513 | echo -e "\nCleaning up key files."
514 | rm ./VMWARE-PACKAGING-GPG-DSA-KEY.pub
515 | rm ./VMWARE-PACKAGING-GPG-RSA-KEY.pub
516 |
517 | echo -e "\nInstalling open vm tools."
518 | apt-get install -q -y open-vm-tools
519 | else
520 | echo -e "\nopen vm tools already installed. Proceeding."
521 | fi
522 | fi
523 |
524 | if [[ $OS = "RedHat" ]];
525 | then
526 | # Are the open-vm-tools present?
527 | openvmtools=$(yum -q list installed open-vm-tools &>/dev/null && echo "yes" || echo "no" )
528 |
529 | if [[ $openvmtools = "no" ]];
530 | then
531 | echo -e "\nopen vm tools not present. Installing."
532 | yum -q -y install open-vm-tools
533 | else
534 | echo -e "\nopen vm tools already installed. Proceeding."
535 | fi
536 | fi
537 | }
538 |
539 | InstallJava()
540 | {
541 | if [[ $OS = "Ubuntu" ]];
542 | then
543 | # Is Oracle Java 1.8 present?
544 | java8=$(dpkg -l | grep "oracle-java8-installer" >/dev/null && echo "yes" || echo "no")
545 |
546 | if [[ $java8 = "no" ]];
547 | then
548 | echo -e "\nOracle Java 8 not present. Installing."
549 | apt install -q -y software-properties-common
550 |
551 | echo -e "\nAdding webupd8team repository to list.\n"
552 | add-apt-repository -y ppa:webupd8team/java
553 | apt-get update -q
554 |
555 | echo -e "\nInstalling Oracle Java 8.\n"
556 | echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections
557 | apt-get install -q -y oracle-java8-installer
558 |
559 | echo -e "\nSetting Oracle Java 8 to the system default.\n"
560 | apt-get install -q -y oracle-java8-set-default
561 |
562 | echo -e "\nSetting JAVA_HOME to use Oracle Java 8.\n"
563 | echo "JAVA_HOME=/usr/lib/jvm/java-8-oracle/jre/bin/java " >> /etc/environment
564 |
565 | echo -e "\nInstalling Java Cryptography Extension 8\n"
566 | curl -v -j -k -L -H "Cookie:oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip > $rootwarloc/jce_policy-8.zip
567 | unzip $rootwarloc/jce_policy-8.zip
568 | cp $rootwarloc/UnlimitedJCEPolicyJDK8/* /usr/lib/jvm/java-8-oracle/jre/lib/security
569 | rm $rootwarloc/jce_policy-8.zip
570 | rm -rf $rootwarloc/UnlimitedJCEPolicyJDK8
571 | else
572 | echo -e "\nOracle Java 8 already installed. Proceeding."
573 | fi
574 | fi
575 |
576 | if [[ $OS = "RedHat" ]];
577 | then
578 | # Is Oracle Java 1.8 present?
579 | java8=$( [ -d "/usr/java" ] && echo "yes" || echo "no" )
580 |
581 | if [[ $java8 = "no" ]];
582 | then
583 | echo -e "\nOracle Java 8 not present. Installing."
584 |
585 | echo -e "\nFinding latest RPM download link.\n"
586 | dl=$( curl -s "https://www.java.com/en/download/manual.jsp" | grep "x64 RPM" | grep -Eo "(http)://[a-zA-Z0-9./?=_-]*" | awk "NR>1{print $1}" )
587 |
588 | echo -e "\nDownloading latest Oracle Java RPM\n"
589 | curl -v -j -k -L -H "Cookie:oraclelicense=accept-securebackup-cookie" "$dl" > $rootwarloc/oracle-java.rpm
590 |
591 | echo -e "\nInstalling Oracle Java RPM\n"
592 | rpm -ivh $rootwarloc/oracle-java.rpm
593 |
594 | echo -e "\nCleaning up downloaded files\n"
595 | rm $rootwarloc/oracle-java.rpm
596 |
597 | echo -e "\nSetting JAVA_HOME to use Oracle Java 8.\n"
598 | echo "JAVA_HOME=/usr/java/default/" >> /etc/environment
599 |
600 | echo -e "\nInstalling Java Cryptography Extension 8\n"
601 | curl -v -j -k -L -H "Cookie:oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip > $rootwarloc/jce_policy-8.zip
602 | unzip $rootwarloc/jce_policy-8.zip
603 | cp $rootwarloc/UnlimitedJCEPolicyJDK8/* /usr/java/default/lib/security
604 | rm $rootwarloc/jce_policy-8.zip
605 | rm -rf $rootwarloc/UnlimitedJCEPolicyJDK8
606 | else
607 | echo -e "\nOracle 8 already installed. Proceeding."
608 | fi
609 | fi
610 | }
611 |
612 | InstallTomcat()
613 | {
614 | # Is Tomcat present?
615 | [ -d "$tomcatloc" ] && tomcat="yes" || tomcat="no"
616 |
617 | if [[ $tomcat = "no" ]];
618 | then
619 | echo -e "\nTomcat 8 not installed. Installing."
620 |
621 | # Create tomcat group
622 | echo -e "\nCreating user group: $user"
623 | groupadd $user
624 |
625 | if [[ $OS = "Ubuntu" ]];
626 | then
627 | echo -e "\nUbuntu detected."
628 |
629 | # Create tomcat user - Ubuntu 14.04 LTS
630 | echo -e "\nCreating tomcat user: $user"
631 | useradd -s /bin/false -g "$user" -d /opt/tomcat "$user"
632 | fi
633 |
634 | if [[ $OS = "RedHat" ]];
635 | then
636 | echo -e "\nRedHat detected."
637 |
638 | # Create tomcat user - RHEL 7.x
639 | echo -e "\nCreating tomcat user: $user"
640 | useradd -M -s /sbin/nologin -g "$user" -d /opt/tomcat "$user"
641 | fi
642 |
643 | # Create systemd script so tomcat can run as a service
644 | echo -e "\nCreating systemd script for Tomcat 8"
645 |
646 | systemd='# Systemd unit file for tomcat
647 | # Created by JSS in a Box
648 | [Unit]
649 | Description=Apache Tomcat Web Application Container
650 | After=syslog.target network.target
651 |
652 | [Service]
653 | Type=forking
654 |
655 | ExecStart=/opt/tomcat8/bin/startup.sh
656 | ExecStop=/opt/tomcat8/bin/shutdown.sh
657 |
658 | User=tomcat
659 | Group=tomcat
660 |
661 | Restart=on-failure
662 | RestartSec=5
663 |
664 | [Install]
665 | WantedBy=multi-user.target
666 | Alias=tomcat.service'
667 |
668 | echo "$systemd" > /lib/systemd/system/tomcat.service
669 | systemctl daemon-reload
670 |
671 | # Find latest tomcat version
672 | echo -e "\nFinding latest Tomcat 8 version"
673 | version=$( curl -s http://tomcat.apache.org/download-80.cgi | grep "
]*>", "")}1' )
674 | echo -e "\nVersion: $version"
675 |
676 | # Work out proper download path
677 | path="http://www.apache.org/dist/tomcat/tomcat-8/v${version}/bin/apache-tomcat-${version}.tar.gz"
678 |
679 | # Grab the latest .tar.gz distribution and install to /opt
680 | echo -e "\nDownloading and installing latest Tomcat 8"
681 | cd /opt
682 | wget $path
683 | tar -xzf /opt/apache-tomcat-${version}.tar.gz
684 | mv /opt/apache-tomcat-${version} "$tomcatloc"
685 | rm /opt/apache-tomcat-${version}.tar.gz
686 |
687 | # Configure permissions on tomcat installation
688 | echo -e "\nConfiguring Tomcat folder permissions"
689 | chown -R $user:$user $tomcatloc
690 | chmod g+rwx $tomcatloc/conf
691 | chmod g+r $tomcatloc/conf/*
692 |
693 | chmod g+rwx $tomcatloc/webapps
694 | chmod g+r $tomcatloc/webapps/*
695 |
696 | # Configure Tomcat environment variable
697 | echo -e "\nSetting Tomcat environment variable"
698 | echo "export CATALINA_HOME="${tomcatloc}"" >> ~/.bashrc
699 | source ~/.bashrc
700 |
701 | # Create Tomcat setenv.sh configuration file
702 | setenv='#!/bin/bash
703 |
704 | # Tomcat configuration file. Generated by JSS-in-a-Box.
705 |
706 | CATALINA_BASE='"'$tomcatloc'"'
707 | CATALINA_HOME="$CATALINA_BASE"
708 | CATALINA_OPTS="-Xms1024m -Xmx3072m"
709 | CATALINA_OPTS="$CATALINA_OPTS -Xss256k"
710 | CATALINA_OPTS="$CATALINA_OPTS -XX:MetaspaceSize=512m"
711 | CATALINA_OPTS="$CATALINA_OPTS -XX:MaxMetaspaceSize=3072m"
712 | CATALINA_OPTS="$CATALINA_OPTS -XX:MaxGCPauseMillis=1500"
713 | CATALINA_OPTS="$CATALINA_OPTS -XX:GCTimeRatio=9"
714 | CATALINA_OPTS="$CATALINA_OPTS -Djava.awt.headless=true"
715 | CATALINA_OPTS="$CATALINA_OPTS -server"
716 | CATALINA_OPTS="$CATALINA_OPTS -XX:+DisableExplicitGC"
717 | CATALINA_OPTS="$CATALINA_OPTS -Djava.security.egd=file:/dev/./urandom"'
718 |
719 | echo "$setenv" > $tomcatloc/bin/setenv.sh
720 | chown tomcat:tomcat $tomcatloc/bin/setenv.sh
721 | chmod 750 $tomcatloc/bin/setenv.sh
722 |
723 | # Clean default tomcat webapps out. We don't require them and could be a security hazard.
724 | echo -e "\nClearing out Tomcat default installations"
725 | rm -rf $tomcatloc/webapps/* 2>/dev/null
726 |
727 | echo -e "\nEnabling Tomcat to start on system restart"
728 | systemctl enable tomcat
729 | else
730 | echo -e "\nTomcat already present. Proceeding."
731 | fi
732 | }
733 |
734 | InstallMySQL()
735 | {
736 | if [[ $OS = "Ubuntu" ]];
737 | then
738 | # Is MySQL 5.7 present?
739 | mysql=$(dpkg -l | grep "mysql-server-5.7" >/dev/null && echo "yes" || echo "no")
740 |
741 | if [[ $mysql = "no" ]];
742 | then
743 | echo -e "\nMySQL 5.7 not present. Installing\n"
744 |
745 | echo -e "\nPreconfiguration of MySQL repo before adding to system\n"
746 | export DEBIAN_FRONTEND=noninteractive
747 | debconf-set-selections <<< "mysql-server-5.7 mysql-server/root_password password $mysqlpw"
748 | debconf-set-selections <<< "mysql-server-5.7 mysql-server/root_password_again password $mysqlpw"
749 |
750 | echo -e "\nAdding MySQL APT repo to system\n"
751 | wget https://dev.mysql.com/get/mysql-apt-config_0.8.3-1_all.deb -P $homefolder
752 | dpkg -i $homefolder/mysql-apt-config_0.8.3-1_all.deb
753 | apt-get update -q
754 | rm $homefolder/mysql-apt-config_0.8.3-1_all.deb
755 |
756 | echo -e "\nInstalling MySQL 5.7\n"
757 | apt-get install -q -y mysql-server
758 |
759 | echo -e "\nEnabling MySQL to start on system restart"
760 | systemctl enable mysql
761 |
762 | echo -e "\nStarting MySQL 5.7"
763 | MySQLService start
764 | else
765 | echo -e "\nMySQL 5.7 already present. Proceeding."
766 | fi
767 | fi
768 |
769 | if [[ $OS = "RedHat" ]];
770 | then
771 | # Is MySQL 5.7 present?
772 | mysql=$(yum -q list installed mysql-community-server &>/dev/null && echo "yes" || echo "no")
773 |
774 | if [[ $mysql = "no" ]];
775 | then
776 | echo -e "\nMySQL 5.7 not present. Installing."
777 |
778 | echo -e "\nAdding MySQL 5.7 to yum repo list\n"
779 | wget https://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm -P $homefolder
780 | rpm -ivh $homefolder/mysql57-community-release-el7-9.noarch.rpm
781 | rm $homefolder/mysql57-community-release-el7-9.noarch.rpm
782 |
783 | echo -e "\nInstalling MySQL 5.7\n"
784 | yum -y --nogpgcheck install mysql-community-server
785 |
786 | echo -e "\nEnabling MySQL to start on system restart"
787 | systemctl enable mysqld
788 |
789 | echo -e "\nStarting MySQL 5.7"
790 | MySQLService start
791 |
792 | echo -e "\nChanging MySQL 5.7 root account password\n"
793 | temppw=$( grep 'temporary password' /var/log/mysqld.log | awk '{ print $11 }' )
794 | mysql -h$mysqlserveraddress -u$mysqluser -p$temppw --connect-expired-password -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '$mysqlpw';" 2>/dev/null
795 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "uninstall plugin validate_password;" 2>/dev/null
796 | else
797 | echo -e "\nMySQL 5.7 already present. Proceeding."
798 | fi
799 | fi
800 | }
801 |
802 | SetupFirewall()
803 | {
804 | # It's time to harden the server firewall.
805 | if [[ $OS = "Ubuntu" ]];
806 | then
807 | # For Ubuntu, we're using UFW to do this.
808 | ufw --force disable # Disables the firewall before we make our changes
809 | ufw --force reset # Resets any firewall rules
810 | ufw allow ssh # Port 22
811 | # ufw allow http # Port 80 (JSS used to use this for xml lookups. Unsure if still needed.)
812 | ufw allow smtp # Port 25
813 | ufw allow ntp # Port 123
814 | # ufw allow ldap # Port 389 (unsecure port. use for internal servers only)
815 | # ufw allow ldaps # Port 636 (ssl ldap. hopefully to be used in preference to above)
816 | ufw allow https # Port 443
817 | ufw allow mysql # Port 3306
818 | ufw allow http-alt # Port 8080 (delete once you got SSL working)
819 | ufw allow 8443 # Port 8443 (delete if you enable 443 redirection or are using 8080 above)
820 | ufw allow 2195 # Apple Push Notification Service
821 | ufw allow 2196 # Apple Push Notification Service
822 | ufw allow 5223 # Apple Push Notification Service
823 | ufw allow 5228 # Google Cloud Messaging
824 | ufw --force enable # Turns on the firewall. May cause ssh disruption in the process.
825 |
826 | # Is https redirect enabled? If so, we have to set up some firewall rules to direct 8443 to 443.
827 | # We're going to use firewall port redirection as the alternative using authbind has proven unreliable.
828 | # And we have to add the rules manually before totally restarting the service too. Fun.
829 | if [[ $httpsredirect = "TRUE" ]];
830 | then
831 | # Append the following lines into the before firewall rules file.
832 | echo "# Port 443 to 8443 redirect rules - added by JSS in a Box" >> /etc/ufw/before.rules
833 | echo "*nat" >> /etc/ufw/before.rules
834 | echo ":PREROUTING ACCEPT [0:0]" >> /etc/ufw/before.rules
835 | echo "-A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443" >> /etc/ufw/before.rules
836 | echo "COMMIT" >> /etc/ufw/before.rules
837 |
838 | # Restart the entire UFW service or this won't work until reboot.
839 | service ufw restart
840 | fi
841 | fi
842 |
843 | if [[ $OS = "RedHat" ]];
844 | then
845 | # For RedHat, we're using FireWallD.
846 | echo -e "\nEnabling FirewallD service."
847 | systemctl start firewalld
848 |
849 | echo -e "\nConfiguring FirewallD service\n"
850 | firewall-cmd --permanent --add-service=ssh
851 | firewall-cmd --permanent --add-service=http
852 | firewall-cmd --permanent --add-service=smtp
853 | firewall-cmd --permanent --add-service=ntp
854 | #firewall-cmd --permanent --add-service=ldap
855 | #firewall-cmd --permanent --add-service=ldaps
856 | firewall-cmd --permanent --add-service=https
857 | firewall-cmd --permanent --add-service=mysql
858 | firewall-cmd --permanent --add-port=8080/tcp # HTTP JSS (delete once you got SSL working)
859 | firewall-cmd --permanent --add-port=8443/tcp # HTTPS JSS (delete 8080 once you got SSL working)
860 | firewall-cmd --permanent --add-port=2195/tcp # Apple Push Notification Service
861 | firewall-cmd --permanent --add-port=2196/tcp # Apple Push Notification Service
862 | firewall-cmd --permanent --add-port=5223/tcp # Apple Push Notification Service
863 | firewall-cmd --permanent --add-port=5228/tcp # Google Cloud Messaging
864 |
865 | echo -e "\nEnabling FirewallD rule changes\n"
866 | firewall-cmd --reload
867 |
868 | echo -e "\nEnabling FirewallD to start on system reboot"
869 | systemctl enable firewalld
870 |
871 | # Is https redirect enabled? If so, we have to set up some firewall rules to direct 443 to 8443.
872 | # A little nicer than UFW, as there are commands to do this instead of directly manipulating firewall rules.
873 | if [[ $httpsredirect = "TRUE" ]];
874 | then
875 | firewall-cmd --permanent --add-masquerade
876 | firewall-cmd --permanent --add-forward-port=port=443:proto=tcp:toport=8443
877 | firewall-cmd --reload
878 | fi
879 | fi
880 | }
881 |
882 | InstallLetsEncrypt()
883 | {
884 | # Is LetsEncrypt present?
885 | # This one is a git clone, rather than an installation for cross distro reasons. We'll be putting this in /opt/letsencrypt
886 | if [ ! -d "/opt/letsencrypt" ];
887 | then
888 | echo -e "\nLetsEncrypt not present. Downloading installation script from dl.eff.org.\n"
889 | mkdir /opt/letsencrypt
890 | cd /opt/letsencrypt
891 | wget https://dl.eff.org/certbot-auto
892 | chmod +x /opt/letsencrypt/certbot-auto
893 | sudo -H /opt/letsencrypt/certbot-auto -n
894 | cd $currentdir
895 | else
896 | echo -e "\nLetsEncrypt is already installed. Proceeding."
897 | return
898 | fi
899 |
900 | # We'll be doing some work with Tomcat so let's stop the service to make sure we don't hurt anything.
901 | echo "\nStopping Tomcat service\n"
902 | TomcatService stop
903 |
904 | # Get LetsEncrypt to generate the appropriate certificate files for later processing.
905 | # We're using sudo -H even as root because there's some weird errors that happen if you don't.
906 | echo -e "\nObtaining Certificate from LetsEncrypt Certificate Authority\n"
907 | if [[ $sslTESTMODE = "TRUE" ]];
908 | then
909 | sudo -H /opt/letsencrypt/certbot-auto certonly --standalone -m $sslemail -d $ssldomain --agree-tos --test-cert
910 | else
911 | sudo -H /opt/letsencrypt/certbot-auto certonly --standalone -m $sslemail -d $ssldomain --agree-tos
912 | fi
913 |
914 | # Code to generate a Java KeyStore for Tomcat from what's provided by LetsEncrypt
915 | # Based on work by Carmelo Scollo (https://melo.myds.me)
916 | # https://community.letsencrypt.org/t/how-to-use-the-certificate-for-tomcat/3677/9
917 |
918 | # Create a keystore folder for Tomcat with the correct permissions
919 | mkdir $sslkeystorepath
920 | chown $user:$user $sslkeystorepath
921 | chmod 755 $sslkeystorepath
922 |
923 | # Ok we got LetsEncrypt certificate files, let's make a PKCS12 combined key file from them.
924 | echo -e "\nMerging LetsEncrypt certificates into a PKCS12 file\n"
925 | openssl pkcs12 \
926 | -export \
927 | -in $lepath/$ssldomain/fullchain.pem \
928 | -inkey $lepath/$ssldomain/privkey.pem \
929 | -out $sslkeystorepath/fullchain_and_key.p12 \
930 | -password pass:$sslkeypass \
931 | -name tomcat
932 |
933 | # Now we convert our .p12 file into a java keystore that Tomcat likes better.
934 | echo -e "\nConverting PKCS12 file into a Java KeyStore\n"
935 | keytool -importkeystore \
936 | -deststorepass $sslkeypass \
937 | -destkeypass $sslkeypass \
938 | -destkeystore $sslkeystorepath/keystore.jks \
939 | -srckeystore $sslkeystorepath/fullchain_and_key.p12 \
940 | -srcstoretype PKCS12 \
941 | -srcstorepass $sslkeypass \
942 | -alias tomcat
943 |
944 | # Clean up on aisle three!
945 | rm $sslkeystorepath/fullchain_and_key.p12
946 |
947 | # Tomcat server.xml was previous prepared in the ConfigureMemoryUseage function.
948 | # Now we disable HTTP and enable the HTTPS connectors
949 |
950 | echo -e "\nDisabling Tomcat HTTP connector\n"
951 | sed -i '75i' $server
953 |
954 | echo -e "\nEnabling Tomcat HTTPS Connector with executor\n"
955 | sed -i '107d' $server
956 | sed -i '86d' $server
957 |
958 | # We're done here. Start 'er up.
959 | TomcatService start
960 |
961 | # Oh wait, we have to set up a periodic renewal since LetsEncrypt doesn't do that for Tomcat
962 | # (at time of coding - 23rd June 2016)
963 | # This should run every night at midnight. LE certs last 90 days but quicker is fine as it won't renew.
964 | # crontab -l | { echo "0 0 * * * $homefolder/jss-in-a-box.sh -s"; } | crontab -
965 |
966 | # We must set up a recurring job to renew the certs using systemd.
967 | # Using https://mjanja.ch/2015/06/replacing-cron-jobs-with-systemd-timers/ as a handy resource
968 |
969 | lerenew='[Unit]
970 | Description=LetsEncrypt Tomcat certificate renewal
971 |
972 | [Timer]
973 | OnCalendar=daily
974 |
975 | [Install]
976 | WantedBy=timers.target'
977 |
978 | echo "$lerenew" > /etc/systemd/system/le-renew.timer
979 |
980 | leservice='[Unit]
981 | Description=LetsEncrypt Tomcat certificate renewal
982 |
983 | [Service]
984 | Type=simple
985 | Nice=19
986 | IOSchedulingClass=2
987 | IOSchedulingPriority=7
988 | ExecStart="$homefolder"/jss-in-a-box.sh -s'
989 |
990 | echo "$leservice" > /etc/systemd/system/le-renew.service
991 |
992 | # Files are in place. Start the timer and enable it for system reboots too.
993 | systemctl start le-renew.timer
994 | systemctl enable le-renew.timer
995 | }
996 |
997 | UpdateLeSSLKeys()
998 | {
999 | # update SSL keys from LetsEncrypt
1000 |
1001 | # Is LetsEncrypt present?
1002 | if [[ $letsencrypt = "FALSE" ]];
1003 | then
1004 | echo -e "\nLetsEncrypt option disabled in script. Cannot proceed.\n"
1005 | return 1
1006 | else
1007 | # Derive the correct file locations from the current tomcat install location
1008 | export sslkeystorepath="$tomcatloc/keystore"
1009 | export server="$tomcatloc/conf/server.xml"
1010 |
1011 | # We'll be doing some work with Tomcat so let's stop the service to make sure we don't hurt anything.
1012 | echo -e "\nStopping Tomcat service\n"
1013 | TomcatService stop
1014 |
1015 | # Get LetsEncrypt to generate the appropriate certificate files for later processing.
1016 | # We're using sudo -H even as root because there's some weird errors that happen if you don't.
1017 | echo -e "\nObtaining Certificate from LetsEncrypt Certificate Authority\n"
1018 | if [[ $sslTESTMODE = "TRUE" ]];
1019 | then
1020 | sudo -H /opt/letsencrypt/certbot-auto renew --dry-run
1021 | else
1022 | sudo -H /opt/letsencrypt/certbot-auto renew --quiet --no-self-upgrade
1023 | fi
1024 |
1025 | # Clean up the old keystore and keys
1026 | rm $sslkeystorepath/keystore.jks
1027 |
1028 | # Ok we got LetsEncrypt certificate files, let's make a PKCS12 combined key file from them.
1029 | echo -e "\nMerging LetsEncrypt certificates into a PKCS12 file"
1030 | openssl pkcs12 \
1031 | -export \
1032 | -in $lepath/$ssldomain/fullchain.pem \
1033 | -inkey $lepath/$ssldomain/privkey.pem \
1034 | -out $sslkeystorepath/fullchain_and_key.p12 \
1035 | -password pass:$sslkeypass \
1036 | -name tomcat
1037 |
1038 | # Now we convert our .p12 file into a java keystore that Tomcat likes better.
1039 | echo -e "\nConverting PKCS12 file into a Java KeyStore"
1040 | keytool -importkeystore \
1041 | -deststorepass $sslkeypass \
1042 | -destkeypass $sslkeypass \
1043 | -destkeystore $sslkeystorepath/keystore.jks \
1044 | -srckeystore $sslkeystorepath/fullchain_and_key.p12 \
1045 | -srcstoretype PKCS12 \
1046 | -srcstorepass $sslkeypass \
1047 | -alias tomcat
1048 |
1049 | # Clean up on aisle three!
1050 | rm $sslkeystorepath/fullchain_and_key.p12
1051 |
1052 | # We're done here. Start 'er up.
1053 | echo -e "\nRestarting Tomcat server"
1054 | TomcatService start
1055 | fi
1056 | }
1057 |
1058 | ConfigureMemoryUsage()
1059 | {
1060 | # Derive the correct file locations from the current OS
1061 | webapps="$tomcatloc/webapps"
1062 | server="$tomcatloc/conf/server.xml"
1063 | sslkeystorepath="$tomcatloc/keystore"
1064 | server="$tomcatloc/conf/server.xml"
1065 | tomcatconf="$tomcatloc/bin"
1066 |
1067 | # Now we work out the correct memory and connection settings
1068 | # What's the default MaxPoolSize?
1069 | MaxPoolSize=$( cat $DataBaseXML | grep MaxPoolSize | sed 's/[^0-9]*//g' )
1070 | echo -e "\nMax Pool Size : $MaxPoolSize"
1071 |
1072 | # How many JSS instances do we currently have? We need at least one, so check for that too.
1073 | NoOfJSSinstances=$( find $webapps/* -maxdepth 0 -type d 2>/dev/null | sed -r 's/^.+\///' | wc -l )
1074 | if [ $NoOfJSSinstances -lt 1 ];
1075 | then
1076 | NoOfJSSinstances=1
1077 | fi
1078 | echo -e "\nNo of current JSS instances: $NoOfJSSinstances"
1079 |
1080 | # MaxThreads = ( MaxPoolSize x 2.5 ) x no of webapps
1081 | MaxThreads=$( awk "BEGIN {print ($MaxPoolSize*2.5)*$NoOfJSSinstances}" )
1082 | echo -e "\nOptimal Max Threads calculated to be: $MaxThreads"
1083 |
1084 | # Derive the maximum number of SQL connections based on the above information
1085 | # Formula is: Maximum Pool Size x No of JSS instances plus one ;)
1086 | MySQLMaxConnections=$( awk "BEGIN {print ($MaxPoolSize*$NoOfJSSinstances)+1}" )
1087 |
1088 | # Work out the amount of system memory, convert to Mb and then subtract 256Mb
1089 | # That'll be what we'll allocate to Java as a maximum memory size. OS needs room too!
1090 | mem=$( grep MemTotal /proc/meminfo | awk '{ print $2 }' )
1091 | memtotal=$( expr $mem / 1024 )
1092 | memtotal=$( expr $memtotal - 256 )
1093 |
1094 | # Well unless we get less than 1024Mb quit as we're in trouble.
1095 | # JSS will not like running that low so you will HAVE to boost your RAM allocation.
1096 | # I've been informed by JAMF support that 8Gb is ideal but I've run it on 4Gb without issue.
1097 | if [ $memtotal -lt 1536 ];
1098 | then
1099 | echo -e "\nERROR: Not enough memory to allocate to Tomcat"
1100 | echo -e "\nNeeded minimum memory: 2048"
1101 | echo -e "\nAvailable memory: $memtotal"
1102 | echo -e "\nPlease increase available RAM on this server."
1103 | fi
1104 |
1105 | echo -e "\nMaximum memory to allocate to Tomcat is: $memtotal Mb"
1106 |
1107 | # Ok has Tomcat previously had it's server.xml altered by this script? Check for the backup.
1108 | if [ ! -f "$server.backup" ];
1109 | then
1110 | # Configure the Tomcat server.xml. None of this stuff is pretty and could be better. Improvements welcome.
1111 | # Let's start by backing up the server.xml file in case things go wrong.
1112 |
1113 | echo -e "\nBacking up $server file"
1114 | cp $server $server.backup
1115 |
1116 | # Delete HTTPS connector settings
1117 | sed -i '84,88d' $server
1118 |
1119 | # Replace HTTPS connector settings
1120 | sed -i '84i' $server
1142 |
1143 | echo -e "\nEnabling Tomcat shared executor"
1144 | sed -i '59d' $server
1145 | sed -i '56d' $server
1146 |
1147 | echo -e "\nDisabling Tomcat default HTTP Connector"
1148 | sed -i '67i' $server
1150 |
1151 | echo -e "\nEnabling Tomcat HTTP Connector with executor"
1152 | sed -i '78d' $server
1153 | sed -i '73d' $server
1154 |
1155 | echo -e "\nAdding Max Threads to HTTP connector"
1156 | sed -i 's/' $server
1161 | fi
1162 |
1163 | # Now for the settings we'll be periodically adjusting
1164 | echo -e "\nConfiguring the TomcatThreadPool executor with current maximum threads"
1165 | sed -i 's/maxThreads="150" /maxThreads="'"$MaxThreads"'" /' $server
1166 |
1167 | # Configure max ram available to Java from what we worked out earlier.
1168 | echo -e "\nConfiguring Java to use $memtotal as max memory."
1169 | sed -i 's/-Xmx.*/-Xmx'"$memtotal"'m"/' $tomcatloc/bin/setenv.sh
1170 | sed -i 's/-XX:MaxMetaspaceSize=.*/-XX:MaxMetaspaceSize='"$memtotal"'m"/' $tomcatloc/bin/setenv.sh
1171 |
1172 | if [[ $OS = "Ubuntu" ]];
1173 | then
1174 | # MySQL
1175 | echo -e "\nConfiguring MySQL max connections to $MySQLMaxConnections"
1176 | sed -i 's/max_connections.*/max_connections = '$MySQLMaxConnections'/' $ubmycnfloc
1177 | fi
1178 |
1179 | if [[ $OS = "RedHat" ]];
1180 | then
1181 | # MySQL
1182 | echo -e "\nConfiguring MySQL max connections to: $MySQLMaxConnections"
1183 | sed -i 's/max_connections.*/max_connections = '$MySQLMaxConnections'/' $rhmycnfloc
1184 | fi
1185 |
1186 | # Time to restart MySQL and Tomcat
1187 | TomcatService stop
1188 | MySQLService restart
1189 | TomcatService start
1190 | }
1191 |
1192 | InitialiseServer()
1193 | {
1194 | # This is to make sure the appropriate services and software are installed and configured.
1195 | InstallGit
1196 | InstallCurl
1197 | InstallWget
1198 | InstallUnzip
1199 | InstallFirewall
1200 | InstallOpenSSH
1201 | InstallOpenVMTools
1202 | InstallJava # This includes the Cryptography Extensions
1203 | InstallTomcat
1204 | InstallMySQL
1205 | ConfigureMemoryUsage
1206 | SetupLogs
1207 |
1208 | if [[ $letsencrypt = TRUE ]];
1209 | then
1210 | InstallLetsEncrypt
1211 | fi
1212 |
1213 | SetupFirewall
1214 | }
1215 |
1216 | CreateNewInstance()
1217 | {
1218 | # Check for presence of Tomcat and MySQL before proceeding
1219 | [ -d "$tomcatloc" ] && tomcat="yes" || tomcat="no"
1220 | CheckMySQL
1221 |
1222 | if [[ $tomcat = "no" || $mysql = "no" ]];
1223 | then
1224 | echo -e "\nTomcat 8 / MySQL not present. Please install before trying again.\n"
1225 | return 1
1226 | fi
1227 |
1228 | # Call function to show all directory names in the tomcat webapps folder
1229 | InstanceList
1230 |
1231 | # Prompt for new instance name
1232 | echo -e "\nPlease enter a new instance name. (Or ROOT for a non-context JSS / enter key to skip)\n"
1233 | read -p "Name : " instance
1234 |
1235 | # Check for the skip
1236 | if [[ $instance = "" ]];
1237 | then
1238 | echo -e "\nSkipping instance creation.\n"
1239 | return
1240 | fi
1241 |
1242 | # Does this name already exist? If so, ask again.
1243 | webapps=($(find $webapploc/* -maxdepth 0 -type d 2>/dev/null | sed -r 's/^.+\///'))
1244 | [[ " ${webapps[@]} " =~ " $instance " ]] && found=true || found=false
1245 |
1246 | if [[ $found = true ]];
1247 | then
1248 | echo -e "\nInstance name already exists.\n"
1249 | return 1
1250 | fi
1251 |
1252 | # Stop tomcat service
1253 | TomcatService stop
1254 |
1255 | # Prep variables for future use based on current OS
1256 | SetupTomcatUser
1257 |
1258 | # Create the new database
1259 | echo -e "\nCreating new database for instance: $instance "
1260 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "CREATE DATABASE $instance;" 2>/dev/null
1261 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "GRANT ALL ON $instance.* TO $dbuser@$mysqlserveraddress IDENTIFIED BY '$dbpass';" 2>/dev/null
1262 |
1263 | # Create the new tomcat instance
1264 | echo -e "\nInstalling JSS application to new instance: $instance"
1265 |
1266 | # Check if installing ROOT, if so just copy the file to the webapps folder
1267 | # Otherwise make a copy of the ROOT.war, rename it to the instance name and
1268 | # then move that to the webapps folder.
1269 | if [[ $instance = "ROOT" ]];
1270 | then
1271 | cp $rootwarloc/ROOT.war $webapploc && unzip -oq $webapploc/ROOT.war -d $webapploc/ROOT
1272 | else
1273 | cp $rootwarloc/ROOT.war $webapploc/$instance.war && unzip -oq $webapploc/$instance.war -d $webapploc/$instance
1274 | fi
1275 |
1276 | # Create a specific DataBase.xml file for this new instance
1277 | echo -e "\nPreparing DataBase.xml for new instance: $instance"
1278 | sed -i "s/\(\).*\(<\/ServerName.*\)/\1$mysqlserveraddress\2/" $DataBaseXML
1279 | sed -i "s/\(\).*\(<\/DataBaseName.*\)/\1$instance\2/" $DataBaseXML
1280 | sed -i "s/\(\).*\(<\/DataBaseUser.*\)/\1$dbuser\2/" $DataBaseXML
1281 | sed -i "s/\(\).*\(<\/DataBasePassword.*\)/\1$dbpass\2/" $DataBaseXML
1282 |
1283 | # Wait for allow Tomcat to expand the .war file we copied over.
1284 | echo -e "\nWaiting for .war file to be expanded"
1285 | while [ ! -d "$webapploc/$instance" ]
1286 | do
1287 | echo -e "Awaiting Tomcat to expand instance: $instance"
1288 | sleep 3
1289 | done
1290 | sleep 5
1291 |
1292 | # Copy the new file over the top of the existing file.
1293 | echo -e "\nCopying the replacement DataBase.xml file into new instance: $instance"
1294 | cp "$DataBaseXML" $webapploc/$instance/$DataBaseLoc/DataBase.xml
1295 |
1296 | # Create the instance name and empty log files with an exception for ROOT
1297 | echo -e "\nCreating log files for new instance: $instance"
1298 | if [[ $instance = "ROOT" ]];
1299 | then
1300 | touch $logfiles/JAMFChangeManagement.log
1301 | touch $logfiles/JAMFSoftwareServer.log
1302 | touch $logfiles/JSSAccess.log
1303 | chown -R $user:$user $logfiles
1304 | else
1305 | mkdir $logfiles/$instance
1306 | touch $logfiles/$instance/JAMFChangeManagement.log
1307 | touch $logfiles/$instance/JAMFSoftwareServer.log
1308 | touch $logfiles/$instance/JSSAccess.log
1309 | chown -R $user:$user $logfiles/$instance
1310 | fi
1311 |
1312 | # Finally modify the log4j file inside the new instance to point to the right files/folders
1313 | echo -e "\nModifying new instance: $instance to point to new log files"
1314 | if [[ $instance = "ROOT" ]];
1315 | then
1316 | sed -i "s@log4j.appender.JAMFCMFILE.File=.*@log4j.appender.JAMFCMFILE.File=$logfiles/JAMFChangeManagement.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties
1317 | sed -i "s@log4j.appender.JAMF.File=.*@log4j.appender.JAMF.File=$logfiles/JAMFSoftwareServer.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties
1318 | sed -i "s@log4j.appender.JSSACCESSLOG.File=.*@log4j.appender.JSSACCESSLOG.File=$logfiles/JSSAccess.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties
1319 | else
1320 | sed -i "s@log4j.appender.JAMFCMFILE.File=.*@log4j.appender.JAMFCMFILE.File=$logfiles/$instance/JAMFChangeManagement.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties
1321 | sed -i "s@log4j.appender.JAMF.File=.*@log4j.appender.JAMF.File=$logfiles/$instance/JAMFSoftwareServer.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties
1322 | sed -i "s@log4j.appender.JSSACCESSLOG.File=.*@log4j.appender.JSSACCESSLOG.File=$logfiles/$instance/JSSAccess.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties
1323 | fi
1324 |
1325 | # Make sure folder ownership is correctly set to Tomcat user or bad things happen!
1326 | chown -R $user:$user $webapploc/
1327 |
1328 | # Recalculate memory usage since we've made changes
1329 | ConfigureMemoryUsage
1330 | }
1331 |
1332 | DeleteInstance()
1333 | {
1334 | # Check for presence of Tomcat and MySQL before proceeding
1335 | [ -d "$tomcatloc" ] && tomcat="yes" || tomcat="no"
1336 | CheckMySQL
1337 |
1338 | if [[ $tomcat = "no" || $mysql = "no" ]];
1339 | then
1340 | echo -e "\nTomcat 8 / MySQL not present. Please install before trying again."
1341 | return 1
1342 | fi
1343 |
1344 | # Call function to show all directory names in the tomcat webapps folder
1345 | InstanceList
1346 |
1347 | # Prompt for the instance name
1348 | echo -e "\n"
1349 | read -p "Please enter a JSS instance to delete (or enter to skip) : " instance
1350 |
1351 | # Does this name already exist?
1352 | webapps=($(find $tomcatloc/webapps/* -maxdepth 0 -type d | sed -r 's/^.+\///'))
1353 | [[ " ${webapps[@]} " =~ " $instance " ]] && found=true || found=false
1354 |
1355 | if [[ $found = false ]];
1356 | then
1357 | echo -e "\nInstance name does not exist."
1358 | return 1
1359 | fi
1360 |
1361 | # It does exist. Are they sure? Very very very VERY sure?
1362 | echo -e "\nWARNING: This will restart the Tomcat service!\n"
1363 | read -p "Are you completely certain? There is NO RECOVERY from this! (Y/N) : " areyousure
1364 |
1365 | case "$areyousure" in
1366 |
1367 | Y|y)
1368 |
1369 | # Stop the tomcat service
1370 | echo -e "\nStopping Tomcat service.\n"
1371 | TomcatService stop
1372 |
1373 | # Delete the tomcat ROOT.war folder
1374 | echo -e "\nDeleting Tomcat instance: $instance"
1375 | rm $tomcatloc/webapps/$instance.war 2>/dev/null
1376 | rm -rf $tomcatloc/webapps/$instance
1377 |
1378 | # Delete the database
1379 | echo -e "\nDeleting database for instance: $instance"
1380 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "DROP DATABASE $instance;" 2>/dev/null
1381 |
1382 | # Delete the logfiles
1383 | echo -e "\nDeleting log files for instance: $instance"
1384 | if [[ $instance = "ROOT" ]];
1385 | then
1386 | rm $logfiles/JAMFSoftwareServer.log 2>/dev/null
1387 | rm $logfiles/JAMFChangeManagement.log 2>/dev/null
1388 | rm $logfiles/JSSAccess.log 2>/dev/null
1389 | else
1390 | rm -rf $logfiles/$instance 2>/dev/null
1391 | fi
1392 |
1393 | # Delete the tomcat cache folder
1394 | echo -e "\nDeleting Tomcat cache folder for instance: $instance"
1395 | if [[ $instance = "ROOT" ]];
1396 | then
1397 | rm -rf $cacheloc/_ 2>/dev/null
1398 | rm -rf $cacheloc/ROOT 2>/dev/null
1399 | else
1400 | rm -rf $cacheloc/$instance 2>/dev/null
1401 | fi
1402 |
1403 | # Recalculate memory usage since we've made changes
1404 | ConfigureMemoryUsage
1405 | ;;
1406 |
1407 | *)
1408 | echo -e "\nSkipping deletion of instance"
1409 | ;;
1410 |
1411 | esac
1412 | }
1413 |
1414 | DumpDatabase()
1415 | {
1416 | # Is MySQL 5.7 present?
1417 | CheckMySQL
1418 |
1419 | if [[ $mysql = "no" ]];
1420 | then
1421 | echo -e "\nMySQL 5.7 not installed. Please install before trying again.\n"
1422 | return 1
1423 | fi
1424 |
1425 | # Shows all JSS databases in MySQL but removing the SQL server specific ones.
1426 | echo -e "\nJSS Database List\n-----------------\n"
1427 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -Bse "SHOW DATABASES;" 2>/dev/null | grep -v "mysql" | grep -E -v "(information|performance)_schema"
1428 |
1429 | # Choose either a single instance or all of them
1430 | echo -e "\n"
1431 | read -p "Please enter an instance name to dump (or ALL for entire database) : " instance
1432 |
1433 | # Has the entire database been selected?
1434 | if [[ $instance = "ALL" ]];
1435 | then
1436 | echo -e "\nDumping all databases to files."
1437 | databases=$( mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -Bse "SHOW DATABASES;" 2>/dev/null | grep -v "mysql" | grep -E -v "(information|performance)_schema" )
1438 |
1439 | # Stop the tomcat service
1440 | echo -e "\nStopping Tomcat service."
1441 | TomcatService stop
1442 |
1443 | for db in $databases; do
1444 | echo "Dumping database: $db"
1445 | mysqldump -h$mysqlserveraddress -u$mysqluser -p$mysqlpw $db 2>/dev/null | gzip > $rootwarloc/$db.sql.gz
1446 | done
1447 |
1448 | # Restart tomcat
1449 | echo -e "\nRestarting Tomcat service"
1450 | TomcatService restart
1451 | return
1452 | fi
1453 |
1454 | # Does this name already exist?
1455 | dbs=($(mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -Bse "SHOW DATABASES;" 2>/dev/null | grep -v "mysql" | grep -E -v "(information|performance)_schema"))
1456 | [[ " ${dbs[@]} " =~ " $instance " ]] && found=true || found=false
1457 |
1458 | if [[ $found = false ]];
1459 | then
1460 | echo -e "\nInstance name does not exist."
1461 | return 1
1462 | fi
1463 |
1464 | # Dump selected database table
1465 | echo -e "\nDumping database $instance ..."
1466 | mysqldump -h$mysqlserveraddress -u$mysqluser -p$mysqlpw $instance 2>/dev/null | gzip > $rootwarloc/$instance.sql.gz
1467 | }
1468 |
1469 | UploadDatabase()
1470 | {
1471 | # Is MySQL 5.7 present?
1472 | CheckMySQL
1473 |
1474 | if [[ $mysql = "no" ]];
1475 | then
1476 | echo -e "\nMySQL 5.7 not installed. Please install before trying again.\n"
1477 | return 1
1478 | fi
1479 |
1480 | # Show list of backup files
1481 | echo -e "\nDatabase Backup List\n-----------------\n"
1482 | find $rootwarloc/*.sql.gz -maxdepth 0 | sed -r 's/^.+\///'
1483 |
1484 | # Ask which file to restore
1485 | echo -e "\n"
1486 | read -p "Please enter filename to restore (enter to skip / ALL for everything!) : " dbname
1487 |
1488 | # Has the entire database been selected?
1489 | if [[ $dbname = "ALL" ]];
1490 | then
1491 | echo -e "\nWARNING: This will overwrite ALL existing MySQL database(s)!\n"
1492 | echo -e "This will stop Tomcat from running while the process completes.\n"
1493 | read -p "Are you completely certain? (Y/N) : " areyousure
1494 |
1495 | case "$areyousure" in
1496 |
1497 | Y|y)
1498 | # Stop the tomcat service
1499 | echo -e "\nStopping Tomcat service."
1500 | TomcatService stop
1501 |
1502 | echo -e "\nImporting all database files."
1503 | databases=($(find $rootwarloc/*.sql.gz -maxdepth 0 | sed -r 's/^.+\///'))
1504 |
1505 | for (( i=0; i<${#databases[@]}; i++ ));
1506 | do
1507 | # Work out what the database name is without the .sql.gz on the end of it!
1508 | db="${databases[i]%.sql.gz}"
1509 |
1510 | echo -e "\nDropping existing database for instance: ${databases[i]} "
1511 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "drop database $db;" 2>/dev/null
1512 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "create database $db;" 2>/dev/null
1513 |
1514 | echo -e "\nImporting database: ${databases[i]}"
1515 | gzip -dc < $rootwarloc/${databases[i]} | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw $db 2>/dev/null
1516 |
1517 | echo -e "\nRe-establishing grants for database: ${databases[i]}"
1518 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "GRANT ALL ON $db.* TO $dbuser@$mysqlserveraddress IDENTIFIED BY '$dbpass';" 2>/dev/null
1519 |
1520 | echo -e "\nRepair and Optimise uploaded database: ${databases[i]}"
1521 | mysqlcheck -h$mysqlserveraddress -u$mysqluser -p$mysqlpw --auto-repair --optimize $db 2>&1
1522 | done
1523 |
1524 | # Recalculate memory usage since we've made changes
1525 | ConfigureMemoryUsage
1526 |
1527 | return
1528 | ;;
1529 |
1530 | *)
1531 | echo -e "\nSkipping database restoration"
1532 | return 1
1533 | ;;
1534 |
1535 | esac
1536 | fi
1537 |
1538 | # Does this name already exist?.
1539 | backups=($(find $rootwarloc/*.sql.gz -maxdepth 0 | sed -r 's/^.+\///'))
1540 | [[ " ${backups[@]} " =~ " $dbname " ]] && found=true || found=false
1541 |
1542 | if [[ $found = false ]];
1543 | then
1544 | echo -e "\nIncorrect or missing database filename."
1545 | return 1
1546 | fi
1547 |
1548 | # It does exist. Are they sure? Very very very VERY sure?
1549 |
1550 | echo -e "\nWARNING: This will overwrite any existing MySQL database(s)!\n"
1551 | echo -e "This will stop Tomcat from running while the process completes.\n"
1552 | read -p "Are you completely certain? (Y/N) : " areyousure
1553 |
1554 | case "$areyousure" in
1555 |
1556 | Y|y)
1557 | # Stop the tomcat service
1558 | echo -e "\nStopping Tomcat service."
1559 | TomcatService stop
1560 |
1561 | # Work out what the database name is without the .sql.gz on the end of it!
1562 | db="${dbname%.sql.gz}"
1563 |
1564 | echo -e "\nDropping existing database for instance: $dbname "
1565 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "drop database $db;" 2>/dev/null
1566 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "create database $db;" 2>/dev/null
1567 |
1568 | # Upload the selected database dump
1569 | echo -e "\nImporting database: $dbname"
1570 | gzip -dc < $rootwarloc/$dbname | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw $db
1571 |
1572 | echo -e "\nRe-establishing grants for database: $dbname"
1573 | mysql -h$mysqlserveraddress -u$mysqluser -p$mysqlpw -e "GRANT ALL ON $db.* TO $dbuser@$mysqlserveraddress IDENTIFIED BY '$dbpass';" 2>/dev/null
1574 |
1575 | echo -e "\nRepair and Optimise uploaded database: ${databases[i]}"
1576 | mysqlcheck -h$mysqlserveraddress -u$mysqluser -p$mysqlpw --auto-repair --optimize $db 2>/dev/null
1577 |
1578 | # Recalculate memory usage since we've made changes
1579 | ConfigureMemoryUsage
1580 | ;;
1581 |
1582 | *)
1583 | echo -e "\nSkipping database restoration"
1584 | ;;
1585 |
1586 | esac
1587 | }
1588 |
1589 | UpgradeInstance()
1590 | {
1591 | # Check for presence of Tomcat and MySQL before proceeding
1592 | [ -d "$tomcatloc" ] && tomcat="yes" || tomcat="no"
1593 | CheckMySQL
1594 |
1595 | if [[ $tomcat = "no" || $mysql = "no" ]];
1596 | then
1597 | echo -e "\nTomcat 8 / MySQL not present. Please install before trying again."
1598 | return 1
1599 | fi
1600 |
1601 | # Call function to show all directory names in the tomcat webapps folder
1602 | InstanceList
1603 |
1604 | # Prompt for the instance name.
1605 | echo -e "\n"
1606 | read -p "Please enter a JSS instance to upgrade (or enter to skip) : " instance
1607 |
1608 | # Does this name already exist?.
1609 | webapps=($(find $webapploc/* -maxdepth 0 -type d | sed -r 's/^.+\///'))
1610 | [[ " ${webapps[@]} " =~ " $instance " ]] && found=true || found=false
1611 |
1612 | if [[ $found = false ]];
1613 | then
1614 | echo -e "\nInstance name does not exist."
1615 | return 1
1616 | fi
1617 |
1618 | # It does exist. Are they sure? Very very very VERY sure?
1619 | echo -e "\nWARNING: This will restart the Tomcat service!\n"
1620 | echo -e "\nThe upgrade will be performed with the ROOT.war file located in $rootwarloc "
1621 | read -p "Are you completely certain? (Y/N) : " areyousure
1622 |
1623 | case "$areyousure" in
1624 |
1625 | Y|y)
1626 | # Stop the tomcat service
1627 | echo -e "\nStopping Tomcat service."
1628 | TomcatService stop
1629 |
1630 | # Backup the /WEB-INF/xml/DataBase.xml file
1631 | echo -e "\nBacking up DataBase.xml of instance: $instance"
1632 | cp $webapploc/$instance/$DataBaseLoc/DataBase.xml /tmp
1633 |
1634 | # Delete the tomcat ROOT.war folder
1635 | echo -e "\nDeleting Tomcat instance: $instance"
1636 | rm $webapploc/$instance.war
1637 | rm -rf $webapploc/$instance
1638 |
1639 | # Rename, copy and expand the replacement tomcat ROOT.war file
1640 | echo -e "\nReplacing Tomcat instance: $instance"
1641 | cp $rootwarloc/ROOT.war $webapploc/$instance.war && unzip -oq $webapploc/$instance.war -d $webapploc/$instance
1642 |
1643 | # Wait for allow Tomcat to expand the .war file we copied over.
1644 | echo -e "\nWaiting for .war file to be expanded"
1645 | while [ ! -d "$webapploc/$instance" ]
1646 | do
1647 | echo -e "Awaiting Tomcat to expand instance: $instance"
1648 | sleep 3
1649 | done
1650 | sleep 5
1651 |
1652 | # Modify the log4j file inside the new instance to point to the right files/folders
1653 | echo -e "\nModifying new instance: $instance to point to new log files"
1654 | if [[ $instance = "ROOT" ]];
1655 | then
1656 | sed -i "s@log4j.appender.JAMFCMFILE.File=.*@log4j.appender.JAMFCMFILE.File=$logfiles/JAMFChangeManagement.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties
1657 | sed -i "s@log4j.appender.JAMF.File=.*@log4j.appender.JAMF.File=$logfiles/JAMFSoftwareServer.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties
1658 | sed -i "s@log4j.appender.JSSACCESSLOG.File=.*@log4j.appender.JSSACCESSLOG.File=$logfiles/JSSAccess.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties
1659 | else
1660 | sed -i "s@log4j.appender.JAMFCMFILE.File=.*@log4j.appender.JAMFCMFILE.File=$logfiles/$instance/JAMFChangeManagement.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties
1661 | sed -i "s@log4j.appender.JAMF.File=.*@log4j.appender.JAMF.File=$logfiles/$instance/JAMFSoftwareServer.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties
1662 | sed -i "s@log4j.appender.JSSACCESSLOG.File=.*@log4j.appender.JSSACCESSLOG.File=$logfiles/$instance/JSSAccess.log@" $webapploc/$instance/WEB-INF/classes/log4j.properties
1663 | fi
1664 |
1665 | # Copy back the DataBase.xml file
1666 | echo -e "\nCopying back DataBase.xml of instance: $instance"
1667 | mv -f /tmp/DataBase.xml $webapploc/$instance/$DataBaseLoc
1668 |
1669 | # Make sure folder ownership is correctly set to Tomcat user or bad things happen!
1670 | chown -R $user:$user $webapploc/
1671 |
1672 | # Restart tomcat
1673 | echo -e "\nRestarting Tomcat service"
1674 | TomcatService restart
1675 | ;;
1676 |
1677 | *)
1678 | echo -e "\nSkipping upgrade of instance"
1679 | ;;
1680 |
1681 | esac
1682 | }
1683 |
1684 | UpgradeAllInstances() {
1685 | # Check for presence of Tomcat and MySQL before proceeding
1686 | [ -d "$tomcatloc" ] && tomcat="yes" || tomcat="no"
1687 | CheckMySQL
1688 |
1689 | if [[ $tomcat = "no" || $mysql = "no" ]];
1690 | then
1691 | echo -e "\nTomcat 8 / MySQL not present. Please install before trying again."
1692 | return 1
1693 | fi
1694 |
1695 | # It does exist. Are they sure? Very very very VERY sure?
1696 | echo -e "\nWARNING: This will restart the Tomcat service and upgrade ALL JSS instances!"
1697 | echo -e "\nThe upgrade will be performed with the ROOT.war file located in $rootwarloc "
1698 | read -p "Are you completely certain you wish to upgrade ALL instances? (Y/N) : " areyousure
1699 |
1700 | case "$areyousure" in
1701 |
1702 | Y|y)
1703 | # Grab an array containing all current JSS instances for processing.
1704 | webapps=($(find $webapploc/* -maxdepth 0 -type d | sed -r 's/^.+\///'))
1705 |
1706 | # Stop the tomcat service
1707 | echo -e "\nStopping Tomcat service.\n"
1708 | TomcatService stop
1709 |
1710 | # Start the upgrade processing loop here.
1711 | for (( i=0; i<${#webapps[@]}; i++ ));
1712 | do
1713 |
1714 | # Line feed for clarity
1715 | echo -e "\n"
1716 |
1717 | # Backup the /WEB-INF/xml/DataBase.xml file
1718 | echo -e "Backing up DataBase.xml of instance: ${webapps[i]}"
1719 | mv $webapploc/${webapps[i]}/$DataBaseLoc/DataBase.xml /tmp
1720 |
1721 | # Delete the tomcat ROOT.war folder
1722 | echo -e "Deleting Tomcat instance: ${webapps[i]}"
1723 | rm $webapploc/${webapps[i]}.war
1724 | rm -rf $webapploc/${webapps[i]}
1725 |
1726 | # Rename, copy and expand the replacement tomcat ROOT.war file
1727 | echo -e "Replacing Tomcat instance: ${webapps[i]}"
1728 | cp $rootwarloc/ROOT.war $webapploc/${webapps[i]}.war && unzip -oq $webapploc/${webapps[i]}.war -d $webapploc/${webapps[i]}
1729 |
1730 | # Wait for allow Tomcat to expand the .war file we copied over.
1731 | echo -e "\nWaiting for the .war file to be expanded"
1732 | while [ ! -d '$rootwarloc/$instance' ]
1733 | do
1734 | sleep 1
1735 | done
1736 | sleep 5
1737 |
1738 | # Modify the log4j file inside the new instance to point to the right files/folders
1739 | echo -e "\nModifying new instance: $instance to point to new log files"
1740 | if [[ $instance = "ROOT" ]];
1741 | then
1742 | sed -i "s@log4j.appender.JAMFCMFILE.File=.*@log4j.appender.JAMFCMFILE.File=$logfiles/JAMFChangeManagement.log@" $webapploc/${webapps[i]}/WEB-INF/classes/log4j.properties
1743 | sed -i "s@log4j.appender.JAMF.File=.*@log4j.appender.JAMF.File=$logfiles/JAMFSoftwareServer.log@" $webapploc/${webapps[i]}/WEB-INF/classes/log4j.properties
1744 | sed -i "s@log4j.appender.JSSACCESSLOG.File=.*@log4j.appender.JSSACCESSLOG.File=$logfiles/JSSAccess.log@" $webapploc/${webapps[i]}/WEB-INF/classes/log4j.properties
1745 | else
1746 | sed -i "s@log4j.appender.JAMFCMFILE.File=.*@log4j.appender.JAMFCMFILE.File=$logfiles/${webapps[i]}/JAMFChangeManagement.log@" $webapploc/${webapps[i]}/WEB-INF/classes/log4j.properties
1747 | sed -i "s@log4j.appender.JAMF.File=.*@log4j.appender.JAMF.File=$logfiles/${webapps[i]}/JAMFSoftwareServer.log@" $webapploc/${webapps[i]}/WEB-INF/classes/log4j.properties
1748 | sed -i "s@log4j.appender.JSSACCESSLOG.File=.*@log4j.appender.JSSACCESSLOG.File=$logfiles/${webapps[i]}/JSSAccess.log@" $webapploc/${webapps[i]}/WEB-INF/classes/log4j.properties
1749 | fi
1750 |
1751 | # Copy back the DataBase.xml file
1752 | echo -e "Copying back DataBase.xml of instance: ${webapps[i]}"
1753 | mv -f /tmp/DataBase.xml $webapploc/${webapps[i]}/$DataBaseLoc/
1754 |
1755 | # Make sure folder ownership is correctly set to Tomcat user or bad things happen!
1756 | chown -R $user:$user $webapploc/
1757 |
1758 | # Loop finishes here
1759 | done
1760 |
1761 | # Restart tomcat
1762 | echo -e "\nRestarting Tomcat service\n"
1763 | TomcatService restart
1764 | ;;
1765 |
1766 | *)
1767 | echo -e "\nSkipping upgrade of instance"
1768 | ;;
1769 |
1770 | esac
1771 | }
1772 |
1773 | MainMenu()
1774 | {
1775 | # Set IFS to only use new lines as field separator.
1776 | IFS=$'\n'
1777 |
1778 | # Clear Screen
1779 | clear
1780 |
1781 | # Start menu screen here
1782 | echo -e "\n----------------------------------------"
1783 | echo -e "\n JSS in a Box"
1784 | echo -e "\n----------------------------------------"
1785 | echo -e " Version $currentver - $currentverdate"
1786 | echo -e "----------------------------------------\n"
1787 |
1788 | while [[ $choice != "q" ]]
1789 | do
1790 | echo -e "\nMain Menu\n"
1791 | echo -e "1) Check & Install Server Software"
1792 | echo -e "2) Show list of current JSS instances"
1793 | echo -e "3) Create new JSS & Database Instance"
1794 | echo -e "4) Delete existing JSS & Database Instance"
1795 | echo -e "5) Dump MySQL Database to file"
1796 | echo -e "6) Upload MySQL dump to database"
1797 | echo -e "7) Upgrade a single JSS instance"
1798 | echo -e "8) Upgrade ALL JSS instances"
1799 | echo -e "9) Refresh SSL certificates from CA"
1800 | echo -e "q) Exit Script\n"
1801 |
1802 | read -p "Choose an option (1-9 / q) : " choice
1803 |
1804 | case "$choice" in
1805 | 1)
1806 | InitialiseServer ;;
1807 | 2)
1808 | InstanceList ;;
1809 | 3)
1810 | CreateNewInstance ;;
1811 | 4)
1812 | DeleteInstance ;;
1813 | 5)
1814 | DumpDatabase ;;
1815 | 6)
1816 | UploadDatabase ;;
1817 | 7)
1818 | UpgradeInstance ;;
1819 | 8)
1820 | UpgradeAllInstances ;;
1821 | 9)
1822 | UpdateLeSSLKeys ;;
1823 | q)
1824 | echo -e "\nThank you for using JSS in a Box!"
1825 | ;;
1826 | *)
1827 | echo -e "\nIncorrect input. Please try again." ;;
1828 | esac
1829 |
1830 | done
1831 | }
1832 |
1833 | ## Main Code Begins here!
1834 |
1835 | # Check for distribution, user privilege level and required files
1836 |
1837 | WhichDistAmI
1838 | AmIroot
1839 | IsROOTwarPresent
1840 | UpdatePkgMgr
1841 | PrepDBfile
1842 |
1843 | # Parameter checking code here.
1844 |
1845 | case "$1" in
1846 | -d|--dump)
1847 | DumpDatabase
1848 | exit 0
1849 | ;;
1850 |
1851 | -i|--instance)
1852 | InstanceList
1853 | exit 0
1854 | ;;
1855 |
1856 | -u|--upgrade)
1857 | UpgradeAllInstances
1858 | exit 0
1859 | ;;
1860 |
1861 | -s|--ssl)
1862 | UpdateLeSSLKeys
1863 | exit 0
1864 | ;;
1865 |
1866 | -h|--help)
1867 | echo -e "\nJSS in a Box"
1868 | echo -e "Version $currentver - $currentverdate"
1869 | echo -e "\nUsage: sudo ./jss-in-a-box.sh