When running commands that are going to take awhile, I frequently start them with the nohup command, disown the command from the current session or queue them for later execution. The reason is that if I’m running them from a Terminal or SSH session and the session is broken I want to make sure they complete. To schedule a job for later execution, use at. For example, if I want to perform a simple command, I can schedule it in a minute by running it as an echo piped to at:
echo "goldengirlsfix.sh" | at now + 2 minutes
Note, if using 1 minute, you’ll need that to be singular. But you can also disown the job. To do so, end a command with an & symbol. So, running a command or script that will take awhile with an ampersand at the end displays the job number for the command and then you can disown it by running disown followed by -h at the end. for example:
du -d 0 &
If you choose not to disown the job, you can check running jobs using the jobs command at any time:
Nohup runs a command or script in the background even after a shell has been stopped:
nohup cvfsck -nv goldengirls &
The above command runs the command between nohup and the & symbol in the background. By default, you’ll then have the output to the command run in the nohup.out file in your home directory. So if your username were krypted, you could tail the output using the following command:
tail -f /Users/krypted/nohup.out
You can also use screen and then reconnect to that screen. For example, use screen with a -t to create a new screen:
screen -t sanconfigchange
Then run a command:
Then later, reconnect to your screen:
And you can control-n or control-a to scroll through running background processes this way, provided each is in its own screen.
Finally, in AIX you can actually use the bg command. I used to really like this as I could basically move an existing job into the background if I’d already invoked it from a screen/session. For example, you have pid 88909 running and you want to put it into the background. You can just run bg 88909 and throw it into the background, allowing you to close a tty. But then if you’d like to look at it later, you can always pop it back using, you guessed it, fg. This only worked in AIX really, but is a great process management tool.
When bash scripting, a useful command is logger. The logger command allows you to “make entries in the system log.” When using the logger command, you can write to your own entries to the system log. To show how this command works, we’re going to open two terminal windows, preferably side-by-side. In one window, we’re going to look at the output of the system.log file interactively using the tail command with the -f option
tail -f /private/var/log/system.log
In the other window, we’re going to simply enter the logger command followed by the word frogger:
This will show you an entry similar to the following:
Jun 3 00:34:44 ce.pretendco.com krypted: frogger
Congrats, you’ve successfully written your own log entry into the system log. Now that you’ve done that, go ahead and press the up arrow on your keyboard to see the line again and then hit enter. You’ll then see the same line, with the pid more than likely incremented up by one. The pid is the process id of the logger command you just ran. If you run ps you’ll note that the pid is no longer in use.
Next, we’ll create a text file called froggerlog in our home directory, populating it with just the string: mylogdata. This is meant to emulate having written some data into a log file. We’ll do so using the echo command:
echo mylogdata > froggerlog
Now that we have a file, use the -f option to include the contents of the file into the system.log, specifying the path to the file:
logger -f ~/froggerlog
You will then see something like the following, with your mylogdata string in it:
Jun 3 00:37:24 ce.pretendco.com krypted: mylogdata
Using that structure, you can write data into a file and then later dump that data into the log, so as not to fill up the system.log file with tons of random data as it happens. Or you can write directly into the log as needed. It’s good to have choices.
The -i option is used to include the pid for the logger process in each line. But if you go back and add a second line of data into your log file, and re-run the logger command against that file you’ll notice that the pid is included with each line the same no matter whether you use the -i or not, making the -i unnecessary. You will also note that consecutive rows with the same information simply say — last message repeated 1 time —. This helps to keep log files a bit more trim than they otherwise might be if you have, say, 10,000 lines with the same content:
Jun 3 00:50:57 ce.pretendco.com krypted: mylogdata
Jun 3 00:51:17 ce.pretendco.com krypted: 1234
Jun 3 00:51:17 --- last message repeated 1 time ---
Jun 3 00:51:17 ce.pretendco.com krypted: abc
Now, you might find it difficult to see only the pertinent lines to your script. Use the -t option to tag a line, followed by the tag. For example, let’s add myscript into our lines, continuing to write into the system.log using the froggerlog file from earlier:
logger -t myscript -f ~/froggerlog
Note the output contains the myscript tag in front of the pid, in place of the username you were writing entries as:
Jun 3 00:56:28 ce.pretendco.com myscript: mylogdata
Jun 3 00:56:28 ce.pretendco.com myscript: 1234
Jun 3 00:56:28 --- last message repeated 1 time ---
Jun 3 00:56:28 ce.pretendco.com myscript: abc
Messages can be written at various priorities. To set the priority of your entries, use the -p option. After that enter the priority as an integer, using the following:
Alert: Level 1
Error: Level 3
Warning: Level 4
Notice: Level 5
Info: Level 6
Debug: Level 7
For example, to write an alert entry (everyone should see this):
logger -t myscript -f ~/froggerlog -p alert
To write a debug log:
logger -t myscript -f ~/froggerlog -p debug
The alert log is shown but the debug is not. Levels 5-7 are not displayed using a tail of system.log. If you need to verify success or failure of entries, note that logger exits 0 on success but not when an error is encountered. If you’d like to output entries to standard error, you can do so by adding the -s option as well.
The most impactful aspect of the changes in OS X Mountain Lion Server at first appears to be the fact that DNS looks totally different in the Server app than it did in Server Admin. For starters, most of the options are gone from the graphical interface and it looks a lot less complicated, meaning that there are indeed fewer options. However, all of the options previously available are still there. And, the service behaves exactly as it did before, down to the automatically created host name when a server is configured and doesn’t have correctly configured forward and reverse DNS records that match the host name of the computer.
The DNS servicein OS X Mountain Lion Server, as with previous versions, is based on bind 9 (9.8.1 to be exact). This is very much compatible with practically every DNS server in the world, including those hosted on Windows, OS X, Linux and even Zoe-R.
For many, at installation OS X Mountain Lion Server will already be running the DNS service. This is because DNS wasn’t ready for the server when the Server app was first run. In order to protect itself from misconfiguration, the server then configures DNS to what it thinks is appropriate based on the initial setup assistant. While initially the service appears to only be running with the one record, several are actually created. The initial zone, a reverse zone, the NS record for the zone, the NS record for the reverse zone, the reverse record for the initially created zone, etc. To see all of this, open Server app and then click on the DNS service in the list of SERVICES. Then, click on the cog wheel icon below the list of records and click on Show All Records.
Use the Edit button for Forward Servers to configure servers that DNS requests that aren’t resolvable by the local service for. For example, if you want your DNS service to look to 22.214.171.124 and 126.96.36.199 if it can’t find a record and then cache what it finds there, click Edit.
At the Forwarding Servers screen, use the plus sign to assign the two IPs you would like to use. All records are then cached based on TTL of the zone.
By default the “Perform lookups for” option is set to “only some clients”. Click the Edit button here to define what computers can perform DNS lookups through this server.
At the Perform Lookups screen, provide any additional subnets that should be used. If the server should be accessible by anyone anywhere, just set the “Perform lookups for” field at the DNS service screen to “all clients”.
All you have to do to start the DNS is click on the ON button (if it’s not already started, that is). There’s a chance that you won’t want all of the records that are by default entered into the service. But leave it for now, until we’ve covered what everything is. To list the various types of records:
Primary Zone: The DNS “Domain”. For example, www.krypted.com would likely have a primary zone of krypted.com.
Machine Record: An A record for a computer, or a record that tells DNS to resolve whatever name is indicated in the “machine” record to an IP address, whether the IP address is reachable or not.
Name Server: NS record, indicates the authoritative DNS server for each zone. If you only have one DNS server then this should be the server itself.
Reverse Zone: Zone that maps each name that IP addresses within the zone answer with. Reverse Zones are comprised of Reverse Mappings and each octal change in an IP scheme that has records mapped represents a new Reverse Zone.
Reverse Mapping: PTR record, or a record that indicates the name that should respond for a given IP address. These are automatically created for the first IP address listed in a Machine Record.
Alias Record: A CNAME, or a name that points to another name.
Service Record: Records that can hold special types of data that describe where to look for services for a given zone. For example, iCal can leverage service records so that users can just type the username and password during the setup process.
MX Record: Mail Exchanger, points to the IP address of the mail server for a given domain (aka Primary or Secondary Zone).
Secondary Zone: A read only copy of a zone that is copied from the server where it’s a Primary Zone when created and routinely through what is known as a Zone Transfer.
When you click on the plus sign, you can create additional records. Double-clicking on records (including the Zones) brings up a screen to edit the record. The settings for a zone can be seen below.
These include the name for the zone. As you can see, a zone was created with the hostname rather than the actual domain name. This is a problem if you wish to have multiple records in your domain that point to the same host name. Theoretically you could create a zone and a machine record for each host in the domain, but the right way to do things is probably going to be to create a zone for the domain name instead of the host name. So for the above zone, the entry should be pretendco.com rather than c.pretendco.com (the hostname of the computer). Additionally, the TTL (or Time To Live) can be configured, which is referenced here as the “Zone data is valid for” field. If you will be making a lot of changes this value should be as low as possible (the minimum value here is 5 minutes). Once changes are made, the TTL can be set for a larger number in order to reduce the amount of traffic hitting the server (DNS traffic is really light, so probably not a huge deal in most environments using a Mountain Lion Server as their DNS server). Check the box for “Allow zone transfers” if there will be other servers that use this server to lookup records.
Additionally, if the zone is to be a secondary zone configured on another server, you can configure the frequency to perform zone transfers at this screen, how frequently to perform lookups when the primary name server isn’t responsive and when to stop bothering to try if the thing never actually ends up coming back online. Click on Done to commit any changes made, or to save a new record if you’re creating a new zone.
Double-click on a Machine record next (or click plus to add one). Here, provide a hostname along with an IP address and indicate the Zone that the record lives in. The IP Addresses field seems to allow for multiple IPs, which is common in round robin DNS, or when one name points to multiple servers and lookups rotate amongst the servers. However, it’s worth mentioning that when I configure multiple IP addresses, the last one in the list is the only one that gets fed to clients. Therefore, for now at least, you might want to stick with one IP address per name.
Note that the above screen has a match for the host name to the zone name, including the zone name. This is not to be done for manually created records. Enter the name of a record, such as www for the zone called, for example, krypted.com and not www.krypted.com in the Host Name record, or you will end up creating a host called www.krypted.com.krypted.com, which is likely not very desirable. Given that this wasn’t the default behavior back in Server Admin, I personally consider this something that will likely get fixed in the future. Click Done to commit the changes or create the new record.
Next, let’s create a MX record for the domain. We’re going to stick with the c.pretendco.com subdomain as it provides us with a nice walled garden for our DNS. To create the MX for the domain, click on the plus sign at the list of records.
Select the appropriate zone in the Zone field (if you have multiple zones). Then type the name of the A record that you will be pointing mail to. Most likely, this would be a machine record called simply mail, in this case for pretendco.com, so mail.pretendco.com. If you have multiple MX records, increment the priority number for the lower priority servers.
As a full example, let’s create a zone and some records from scratch. Let’s setup this zone for an Xsan metadata network, called krypted.xsan. Then, let’s create our metadata controller record as starbuck.krypted.xsan to point to 10.0.0.2 and our backup metadata controller record as apollo.krypted.xsan which points to 10.0.0.3. First, click on the plus sign and select Add Primary Zone.
At the zone screen, enter the name krypted.xsan, check the box for Allow zone transfers (there will be a second server) and click on the Done button. Click on the plus sign and then click on Add Machine record.
At the New Machine Record screen, select krypted.xsan as the Zone and then enter starbuck as the Host Name and click on the plus sign for IP Addresses and type in 10.0.0.2. Click on Done to commit the changes.
Repeat the process for Apollo, entering apollo as the Host Name and 10.0.03 as the IP address. Click Done to create the record.
Setting Up Secondary Servers
Now let’s setup a secondary server by leveraging a secondary zone running on a second computer. On the second Mountain Lion Server running on the second server, click on the plus sign for the DNS service and select Add Secondary Zone.
At the Secondary Zone screen, enter krypted.xsan as the name of the zone and then the IP address of the DNS server hosting that domain in the Primary Servers field. Click Done and the initial zone transfer should begin once the DNS service is turned on (if it hasn’t already been enabled).
Managing DNS From The Command Line
Now, all of this is pretty straight forward. Create a zone, create some records inside the zone and you’re good to go. But there are a lot of times when DNS just needs a little more than what the Server app can do for you. For example, round robin DNS records, bind views, etc. Therefore, getting used to the command line is going to be pretty helpful for anyone with more than a handful of records. The first thing to know about the DNS command line in OS X Mountain Lion Server is to do everything possible using the serveradmin command. To start the service, use the start option:
sudo serveradmin start dns
To stop the service, use the stop option:
sudo serveradmin stop dns
To get the status of the service, including how many zones are being hosted, the last time it was started, the status at the moment, the version of bind (9.8.1 right now) and the location of the log files, use the fullstatus option:
sudo serveradmin fullstatus dns
A number of other tasks can be performed using the settings option. For example, to enable Bonjour Client Browsing, an option previously available in Server Admin, use the following command:
sudo serveradmin settings dns:isBonjourClientBrowsingEnabled = yes
Subnets can be created programmatically through serveradmin as well. Let’s look at what our krypted.xsan subnet looks like, by default (replace your zone name w/ krypted.xsan to see your output):
sudo serveradmin settings dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan
Which outputs the following:
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:allowZoneTransfer = yes
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:aliases = _empty_array
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:expire = 1209600
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:serial = 2012080505
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:allow-update = no
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:adminEmail = "firstname.lastname@example.org"
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:machines:_array_index:0:name = "starbuck.krypted.xsan."
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:machines:_array_index:0:ipAddresses:_array_index:0:ipAddress = "10.0.0.2"
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:machines:_array_index:1:name = "apollo.krypted.xsan."
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:machines:_array_index:1:ipAddresses:_array_index:0:ipAddress = "10.0.0.3"
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:nameservers:_array_index:0:name = "krypted.xsan"
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:nameservers:_array_index:0:value = "starbuck.krypted.xsan."
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:refresh = 3600
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:mailExchangers = _empty_array
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:reverseMappings = _empty_array
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:retry = 900
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:timeToLive = 86400
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:serviceRecords = _empty_array
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:bonjourRegistration = yes
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:name = "krypted.xsan"
Now, let’s say we’d like to disable bonjour registration of just this zone, but leave it on for the others on the server:
sudo serveradmin settings dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:krypted.xsan:bonjourRegistration = no
The entire block can be fed in for new zones, if you have a lot of them. Just remember to always make sure that the serial option for each zone is unique. Otherwise the zones will not work properly.
While serveradmin is the preferred way to edit zone data, it isn’t the only way. In /private/var/named are a collection of each zone the server is configured for. Secondary zones are flat and don’t have a lot of data in them, but primary zones contain all the information in the Server app and the serveradmin outputs. To see the contents of our test zone we created, let’s view the /var/named/db.krypted.xsan file (each file name is db. followed by the name of the zone):
The output of which is similar to the following (YMMV based on record composition):
krypted.xsan. 10800 IN SOA krypted.xsan. admin.krypted.xsan. (
2012080507 ; serial
3600 ; refresh (1 hour)
900 ; retry (15 minutes)
1209600 ; expire (2 weeks)
86400 ; minimum (1 day)
)10800 IN NS starbuck.krypted.xsan.
apollo.krypted.xsan. 10800 IN A 10.0.0.3
starbuck.krypted.xsan. 10800 IN A 10.0.0.2
Add another record into the bottom and stop/start DNS to immediately see the ramification of doing so. Overall, DNS is one of those services that seems terribly complicated at first. But once you get used to it, I actually find manually editing zone files far faster and easier than messing around with the Server app or previously Server Admin. However, I also find that occasionally, because the Server app can make changes in there that all my settings will vanish.
Troubleshooting is another place where the command line can be helpful. While logs can be found in the Server app, I prefer to watch log entries live as I perform lookups using the /Library/Logs/named.log file. To do so, run tail -f followed by the name of the file:
tail -f /Library/Logs/named.log
Finally, see http://krypted.com/mac-os-x-server/os-x-server-forcing-dns-propagation for information on forcing DNS propagation if you are having issues with zone transfers.
Because DNS is one of the most critical aspects of getting your server or servers configured properly, set up the name of your server before you do anything else. Then the very first thing you should do when you open the Server app on your first server is configure DNS. The next thing you should do is test DNS. The first thing you should do on each subsequent server is check DNS. Overall, the DNS service is very straight forward, once you get used to setting up records. There is a ton of flexibility around using the command line to manage the service as well; however, be aware when you do so that you could end up loosing data if you aren’t careful not to make any changes in the Server app!
As for getting used to the changes with every new version of OS X, Daniel Graystone once said “She’ll adjust. She’s probably very confused by everything. It’s only natural.”
I was on the phone with someone earlier today and they didn’t realize that they could dynamically watch new lines come into log files in Mac OS X. In order to do this you can use the tail command with the -f switch. So if you want to watch your system.log file and run some processes you think will cause errors you can use the following command:
tail -f system.log
When you’re done watching the log file use the Control-C keystroke to stop.