krypted.com

Tiny Deathstars of Foulness

Migrating file services from a macOS Server to a macOS Client can be a bit traumatic at first. Mostly because the thought itself can be a bit daunting. But once you get started, it’s pretty simple. Mostly because there’s less to do. And that can be a challenge. While there are ways to hack together solutions for network homes and other more advanced features, if you’re doing that, then you’re missing a key point here. 

Let’s start by documenting our existing share points. We’ll do this with the serveradmin command and using the settings verb for the sharing service as follows:

sudo serveradmin settings sharing

Each share is an item in the sharePointList array, with the following:

sharing:sharePointList:_array_id:/Users/charles.edge/Public:nfsExportRecord = _empty_array sharing:sharePointList:_array_id:/Users/charles.edge/Public:smbName = “Charles Edge’s Public Folder” sharing:sharePointList:_array_id:/Users/charles.edge/Public:name = “Charles Edge’s Public Folder” sharing:sharePointList:_array_id:/Users/charles.edge/Public:afpIsGuestAccessEnabled = yes sharing:sharePointList:_array_id:/Users/charles.edge/Public:isIndexingEnabled = no sharing:sharePointList:_array_id:/Users/charles.edge/Public:dsAttrTypeNative\:sharepoint_group_id = “6C37A421-C506-4523-8769-1AF6EA245B68” sharing:sharePointList:_array_id:/Users/charles.edge/Public:mountedOnPath = “/” sharing:sharePointList:_array_id:/Users/charles.edge/Public:dsAttrTypeNative\:sharepoint_account_uuid = “C0405AE4-6CBE-40C7-9584-174687C80C07” sharing:sharePointList:_array_id:/Users/charles.edge/Public:path = “/Users/charles.edge/Public” sharing:sharePointList:_array_id:/Users/charles.edge/Public:smbIsShared = yes sharing:sharePointList:_array_id:/Users/charles.edge/Public:smbIsGuestAccessEnabled = yes sharing:sharePointList:_array_id:/Users/charles.edge/Public:afpName = “Charles Edge’s Public Folder” sharing:sharePointList:_array_id:/Users/charles.edge/Public:dsAttrTypeStandard\:GeneratedUID = “5C13E2AA-A86D-45D0-80B4-00CA86DE2253” sharing:sharePointList:_array_id:/Users/charles.edge/Public:smbDirectoryMask = “755” sharing:sharePointList:_array_id:/Users/charles.edge/Public:afpIsShared = yes sharing:sharePointList:_array_id:/Users/charles.edge/Public:smbCreateMask = “644” sharing:sharePointList:_array_id:/Users/charles.edge/Public:ftpName = “Charles Edge’s Public Folder”

Once you’ve removed the Server app, you’ll be left with using the sharing command. Using that command, you can list shares using the -l option:

sharing -l

That same share then appears as follows:

List of Share Points
name: Charles Edge’s Public Folder
path: /Users/charles.edge/Public
afp: {
name: Charles Edge’s Public Folder
shared: 1
guest access: 1
inherit perms: 0
}
smb: {
name: Charles Edge’s Public Folder
shared: 1
guest access: 1
read-only: 0
sealed: 0
}


Or from the Sharing System Preference Pane.

Now you just have to loop through and create each share (although they should co-exist between tools). To create a share, click on the plus sign under Shared Folders.

You can then browse to the folder you’d like to share. Next, we’ll give access to the directory. Use the plus sign on the right side of the screen and then select the user or group you’d like to add to the list that has access to the directory (while the directory is highlighted in the list on the left).

Once the user is in the list, use the permissions on the right side of the user list to select what level each user or group gets.

You have additional controls for file and folder security that can be set at either the directory that is shared or those below it hierarchically. To do so, highlight the directory and use the Get Info option under the File menu in the Finder.

Note: You can also check the Shared Folder box on these folders to share them, meaning you have one less step once you get used to the workflow!

April 25th, 2018

Posted In: Mac OS X

Tags: , , , , , ,

Synology is able to do everything a macOS Server could do, and more. So if you need to move your VPN service, it’s worth looking at a number of different solutions. The most important question to ask is whether you actually need a VPN any more. If you have git, mail/groupware, or file services that require remote access then you might want to consider moving these into a hosted environment somewhere. But if you need access to the LAN and you’re a small business without other servers, a Synology can be a great place to host your VPN services. 

Before you setup anything new, first snapshot your old settings. Let’s grab  which protocols are enabled, running the following from Terminal:

sudo serveradmin settings vpn:Servers:com.apple.ppp.pptp:enabled

sudo serveradmin settings vpn:Servers:com.apple.ppp.l2tp:enabled

Next, we’ll get the the IP ranges used so we can mimic those (or change them) in the new service:

sudo serveradmin settings vpn:Servers:com.apple.ppp.pptp:IPv4:DestAddressRanges

Now let’s grab the DNS servers handed out so those can be recreated:

sudo serveradmin settings vpn:Servers:com.apple.ppp.pptp:DNS:OfferedServerAddresses:_array_index
sudo serveradmin settings vpn:Servers:com.apple.ppp.l2tp:DNS:OfferedServerAddresses:_array_index

Finally, if you’re using L2TP, let’s grab the shared secret:

sudo serveradmin settings vpn:Servers:com.apple.ppp.l2tp:L2TP:IPSecSharedSecretValue

Once we have all of this information, we can configure the new server using the same settings. To install the VPN service on a Synology, first open the Synology and click on Package Center. From there, click on All and search for VPN.

Then click on the Install button for VPN. Once installed, open VPN Server from the application launcher in the upper left-hand corner of the screen. Initially, you’ll see a list of the services that can be run, which include the familiar PPTP and L2TP, along with the addition of Open VPN.

Before we potentially open up dangerous services to users we might not want to have access to, click on Privilege. Here, enable each service for each user that you want to have access to the VPN services.

Now that we can safely enable and disable each of the services, click on PPTP in the sidebar of the VPN Server app (if you want to provide PPTP-based services to clients).

Here, check the box for “Enable PPTP VPN server” and enter the following information:
  • Dynamic IP address: The first DHCP address that will be given to client computers
  • Maximum connection number: How many addresses that can be handed out (and therefore the maximum number of clients that can connect via PPTP).
  • Maximum number of connections with the same account: How many sessions a given account can have (1 is usually a good number here).
  • Authentication: Best to leave this at MS-CHAP v2 for compatibility, unless you find otherwise.  
  • Encryption: Leave as MPPE optional unless all clients can do MPPE and then you can enforce it for a stronger level of encryption.
  • MTU: 1400 is a good number.
  • Use manual DNS: If clients will connect to services via names once connected to the VPN, I’d put your primary DNS server in this field.

Click Apply and open port 1723 so clients can connect to the service. If you’ll be using L2TP over IPSec, click on “L2TP/IPSec” in the sidebar. The settings are the same as those above, but you can also add a preshared key to the mix. Go ahead and check the enable checkbox, provide the necessary settings from the PPTP list, and provide that key and then click on Apply. Note that the DHCP pools are different between the two services. Point UDP ports 1701, 500, and 4500 at the new server to allow for remote connections and then test that clients can connect.

That’s it. You’ve managed to get a new VPN setup and configured. Provided you used the same IP address, same client secret, and the ports are the same, you’ll then be able to probably use the same profile to install clients that you were using previously.

April 6th, 2018

Posted In: Mac OS X Server, Mac Security, Synology

Tags: , , , , , , ,

People who have managed Open Directory and will be moving to Synology will note that directory services really aren’t nearly as complicated was we’ve made them out to be for years. This is because Apple was protecting us from doing silly things to break our implementations. It was also because Apple bundled a number of seemingly disparate technologies into ldap. It’s worth mentioning that LDAP on a Synology is LDAP. We’re not federating services, we’re not kerberizing services, we’re not augmenting schemas, etc. We can leverage the directory service to provide attributes though, and have that central phone book of user and group memberships we’ve come to depend on directory services to provide.

To get started, open the Package Center and search for Directory. Click Install for the Directory Server and the package will be installed on the Synology.

When the setup is complete, open the Directory Server from the launcher available in the upper right hand corner of the screen. 

The LDAP server isn’t yet running as you need to configure a few settings before starting. At the Settings screen, you can enable the LDAP service by checking the box to “Enable LDAP Service” and providing the hostname (FQDN) of the service along with a password.


Once the service is configured, you’ll have a base DN and a bind DN. These are generated based on the name provided in that FQDN field. For example, if the FQDN is “synology.krypted.com”, its Base DN will be “dc=synology,dc=krypted,dc=com”. And the Bind DN would add a lookup starting a root, then moving into the users container and then the hostname: uid=root,cn=users,dc=synology,dc=krypted,dc=com

If this is for internal use, then it’s all setup. If you’ll be binding external services to this LDAP instance, make sure to open ports 389 (for LDAP) and/or 636 (for LDAP over SSL) as well. 

Once you have information in the service, you’ll want to back it up. Click on Backup and Restore. Then click on Configure.

At the Configure screen, choose a destination.

I prefer using a directory I can then backup with another tool. Once you have defined a place to store your backups using the Destination field, choose a maximum number of backups and configure a schedule for the backups to run (by default backups run at midnight). Then click OK. You now have a functional LDAP service. To create Groups, click on the Group in the left sidebar. 

Here, you can easily create groups by clicking on the Create button. At the wizard, provide a group name and then enter the name of a group (accounting in this example).

Click Next, then Apply to finish creating the group. One you have created your groups, click on User to start entering your users. Click Create. At the User Information screen, enter the name, a description if needed, and the password for a user. You can also restrict password changes and set an expiration for accounts. Click Next to create the user. 

At the next screen, choose what groups the new user will be in and click Next.

Enter any extended attributes at the next screen, if you so choose (useful for directories).

Click Next and then Apply.

For smaller workgroups, you now have a functional LDAP service! If you’d like a nice gui to access more options, look at FUM ( 

https://github.com/futurice/futurice-ldap-user-manager ), LAM ( https://www.ldap-account-manager.org/lamcms/ ), LinID ( http://www.linid.org/welcome/index.html )or other tools. I wrote an article on LDAP SACLs awhile back, so I’ll try and track that down and update it for Synology soon!

April 5th, 2018

Posted In: Mac OS X Server, Synology

Tags: , , , , , , , , ,

Apple won’t be keeping all of the services in macOS Server after the next few months. In the meantime, we have a big old guide to read. I have some overlapping articles I’ve been working on, but I’d say we’re in a similar headspace. The Apple macOS Server Services Migration Guide is available at https://developer.apple.com/support/macos-server/macOS-Server-Service-Migration-Guide.pdf and covers bind, vpnd, freeradius, manual netinstall with bootp and tftp, apache, wordpress, CalendarServer, and ftp. It’s pretty technical, but nothing too crazy in there!

Overall, an easy read and I’m glad to see some content coming out to help admins!

March 30th, 2018

Posted In: Mac OS X Server

Tags: , , , , , , , , , ,

DNS is an integral service to most modern networks. The Domain Name System, or DNS is comprised of hierarchical and decentralized Domain Name Servers, or DNS Servers. This is how we connect to computers and the websites that reside on computers by their names, rather than having to memorize the IP addresses of every single computer out there. So you get to type krypted.com and come to my website instead of typing the IP address. Or more likely, Facebook.com, but just because my website is older, I’m not mad about that. No really…

So you have a macOS Server and you need to take your DNS records out of it and move them to another solution. Luckily, DNS on any operating system is one of the easiest to manage. So let’s start by dumping all of our zone records and settings using the dnsconfig command:

/Applications/Server.app/Contents/ServerRoot/System/Library/PrivateFrameworks/DNSManager.framework/dnsconfig list

ACLs:
com.apple.ServerAdmin.DNS.public
Options:
directory: /Library/Server/named
allow-recursion: com.apple.ServerAdmin.DNS.public 
allow-transfer: none 
forwarders: 8.8.8.8 4.4.4.4 
Views:
com.apple.ServerAdmin.DNS.public
Zones:
test.com
Options:
allow-transfer: none 
allow-update: none 
Resource Recs:
testalias.test.com (CNAME)
test.com (SOA)
test.com (NS)
test.com (MX)
test.test.com (A)
Resource Recs:
no resource recs
0.0.127.in-addr.arpa
Options:
allow-update: none 
Resource Recs:
0.0.127.in-addr.arpa (SOA)
0.0.127.in-addr.arpa (NS)
1.0.0.127.in-addr.arpa (PTR)
0.0.10.in-addr.arpa
Options:
allow-transfer: none 
allow-update: none 
Resource Recs:
1.0.0.10.in-addr.arpa (PTR)
0.0.10.in-addr.arpa (SOA)
0.0.10.in-addr.arpa (NS)

Now that we have our records, let’s think of how to use them in the new server. In the above example, we list test.com as a zone. And in that zone we have an A record for test.test.com and a CNAME for testalias.test.com that points to test.test.com – but we don’t know where test.test.com resolves to. Each of those domains has a corresponding file that starts with db. followed by the name of the domain in the /Library/Server/named directory. So we can cat the test.com file as follows:

cat /Library/Server/named/db.test.com

test.com.   10800 IN SOA test.com. admin.test.com. (
2018033001
3600
900
1209600
86400)
 10800 IN NS test.test.com.
 10800 IN MX 0 test.test.com.
test.test.com.   10800 IN A 10.0.0.1
testalias.test.com.   10800 IN CNAME test.test.com.

Now we know the IP address that each record points to and can start building them out in other systems. If you only have 5-20 records, this is pretty quick and easy. If you have hundreds, then you’re in luck, as those db files per domain are portable between hosts. Some of the settings to look out for from macOS Server include:
  • 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.
  • Mail Exchanger Record (aka 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.
The settings for the domains are as follows:
  • allow-transfer Takes one or more address match list entry. Address match list entries consist of any of these forms: IP addresses, Subnets or Keywords.
  • allow-recursion Takes one or more address match list entry.
  • allow-update Takes one or more address match list entry.
  • allow-query Takes one or more address match list entry.
  • allow-query-cache Takes one or more address match list entry.
  • forwarders Takes one or more IP addresses, e.g. 10.1.1.1
  • directory Takes a directory path
  • tkey-gssapi-credential Takes a kerberos service principal
  • tkey-domain Takes a kerberos realm
  • update-policy Takes one complete update-policy entry where you can grant or deny various matched objects and specify the dentity of the user/machine that is allowed/disallowed to update.. You can also identify match-type (Type of match to be used in evaulating the entry) and match-name (Name used to match) as well as rr-types (Resource record types that can be updated)
You can also use the serveradmin command, and should certainly back up all of your settings and records this way. This is easily done using the serveradmin command as follows:

serveradmin settings dns

And the output would look something like this: 

dns:acls:_array_index:0:name = “com.apple.ServerAdmin.DNS.public”
dns:acls:_array_index:0:addressMatchList:_array_index:0 = “localhost”
dns:acls:_array_index:0:addressMatchList:_array_index:1 = “localnets”
dns:forwarders:_array_index:0 = “8.8.8.8”
dns:forwarders:_array_index:1 = “4.4.4.4”
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:reverseZones:_array_id:0.0.10.in-addr.arpa:aliases = _empty_array
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:reverseZones:_array_id:0.0.10.in-addr.arpa:expire = 1209600
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:reverseZones:_array_id:0.0.10.in-addr.arpa:serial = 2018033001
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:reverseZones:_array_id:0.0.10.in-addr.arpa:allow-update = no
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:reverseZones:_array_id:0.0.10.in-addr.arpa:adminEmail = “admin@0.0.10.in-addr.arpa”
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:reverseZones:_array_id:0.0.10.in-addr.arpa:machines = _empty_array
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:reverseZones:_array_id:0.0.10.in-addr.arpa:nameservers:_array_index:0:name = “0.0.10.in-addr.arpa”
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:reverseZones:_array_id:0.0.10.in-addr.arpa:nameservers:_array_index:0:value = “test.test.com.”
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:reverseZones:_array_id:0.0.10.in-addr.arpa:refresh = 3600
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:reverseZones:_array_id:0.0.10.in-addr.arpa:mailExchangers = _empty_array
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:reverseZones:_array_id:0.0.10.in-addr.arpa:reverseMappings:_array_index:0:value = “test.test.com.”
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:reverseZones:_array_id:0.0.10.in-addr.arpa:reverseMappings:_array_index:0:ipAddress = “10.0.0.1”
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:reverseZones:_array_id:0.0.10.in-addr.arpa:retry = 900
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:reverseZones:_array_id:0.0.10.in-addr.arpa:timeToLive = 86400
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:reverseZones:_array_id:0.0.10.in-addr.arpa:serviceRecords = _empty_array
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:reverseZones:_array_id:0.0.10.in-addr.arpa:name = “0.0.10.in-addr.arpa”
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:reverseZones:_array_id:0.0.10.in-addr.arpa:allowZoneTransfer = no
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:aliases:_array_index:0:name = “testalias.test.com.”
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:aliases:_array_index:0:value = “test.test.com.”
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:expire = 1209600
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:serial = 2018033001
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:allow-update = no
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:adminEmail = “admin@test.com”
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:machines:_array_index:0:name = “test.test.com.”
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:machines:_array_index:0:ipAddresses:_array_index:0:ipAddress = “10.0.0.1”
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:nameservers:_array_index:0:name = “test.com”
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:nameservers:_array_index:0:value = “test.test.com.”
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:refresh = 3600
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:mailExchangers:_array_index:0:address = “test.test.com.”
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:mailExchangers:_array_index:0:priority = 0
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:reverseMappings = _empty_array
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:retry = 900
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:timeToLive = 86400
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:serviceRecords = _empty_array
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:name = “test.com”
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:primaryZones:_array_id:test.com:allowZoneTransfer = no
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:name = “com.apple.ServerAdmin.DNS.public”
dns:views:_array_id:com.apple.ServerAdmin.DNS.public:secondaryZones = _empty_array

Or to output it to a file, just pipe it as follows:

sudo serveradmin settings dns > test.dns

March 30th, 2018

Posted In: Mac OS X Server

Tags: , , ,

The first step to moving services from macOS Server for pretty much all services is to check out the old settings. The second step is to probably ask if where you’re going to put the service is a good idea. For example, these days I prefer to run DHCP services on a network appliance such as a Synology. And so let’s look at how to do that. Here, we’ll use the serveradmin command to view the settings of the DHCP service:

/Applications/Server.app/Contents/ServerRoot/usr/sbin/serveradmin settings dhcp

The output is an array of subnets with different settings per subnet.

dhcp:static_maps = _empty_array
dhcp:subnets:_array_id:22217FF5-4DDB-4841-A731-EF5DA080E672:WINS_primary_server = ""
dhcp:subnets:_array_id:22217FF5-4DDB-4841-A731-EF5DA080E672:dhcp_router = "10.15.40.1"
dhcp:subnets:_array_id:22217FF5-4DDB-4841-A731-EF5DA080E672:WINS_secondary_server = ""
dhcp:subnets:_array_id:22217FF5-4DDB-4841-A731-EF5DA080E672:net_range_start = "10.15.40.2"
dhcp:subnets:_array_id:22217FF5-4DDB-4841-A731-EF5DA080E672:net_range_end = "10.15.43.253"
dhcp:subnets:_array_id:22217FF5-4DDB-4841-A731-EF5DA080E672:dhcp_domain_name = "clients.msp.jamfsw.corp"
dhcp:subnets:_array_id:22217FF5-4DDB-4841-A731-EF5DA080E672:dhcp_domain_name_server:_array_index:0 = "8.8.8.8"
dhcp:subnets:_array_id:22217FF5-4DDB-4841-A731-EF5DA080E672:dhcp_domain_name_server:_array_index:1 = "4.4.4.4"
dhcp:subnets:_array_id:22217FF5-4DDB-4841-A731-EF5DA080E672:lease_max = 36000
dhcp:subnets:_array_id:22217FF5-4DDB-4841-A731-EF5DA080E672:net_mask = "255.255.252.0"
dhcp:subnets:_array_id:22217FF5-4DDB-4841-A731-EF5DA080E672:dhcp_ldap_url = _empty_array
dhcp:subnets:_array_id:22217FF5-4DDB-4841-A731-EF5DA080E672:WINS_node_type = "NOT_SET"
dhcp:subnets:_array_id:22217FF5-4DDB-4841-A731-EF5DA080E672:dhcp_enabled = yes
dhcp:subnets:_array_id:22217FF5-4DDB-4841-A731-EF5DA080E672:WINS_NBDD_server = ""
dhcp:subnets:_array_id:22217FF5-4DDB-4841-A731-EF5DA080E672:net_address = "10.15.40.0"
dhcp:subnets:_array_id:22217FF5-4DDB-4841-A731-EF5DA080E672:WINS_scope_id = ""
dhcp:subnets:_array_id:22217FF5-4DDB-4841-A731-EF5DA080E672:selected_port_name = "en1"
dhcp:subnet_defaults:logVerbosity = "MEDIUM"
dhcp:subnet_defaults:routers:en0 = "10.15.40.1"
dhcp:subnet_defaults:WINS_node_type_list:_array_index:0 = "BROADCAST_B_NODE"
dhcp:subnet_defaults:WINS_node_type_list:_array_index:1 = "HYBRID_H_NODE"
dhcp:subnet_defaults:WINS_node_type_list:_array_index:2 = "NOT_SET"
dhcp:subnet_defaults:WINS_node_type_list:_array_index:3 = "PEER_P_NODE"
dhcp:subnet_defaults:WINS_node_type_list:_array_index:4 = "MIXED_M_NODE"
dhcp:subnet_defaults:WINS_node_type = "NOT_SET"
dhcp:subnet_defaults:dhcp_domain_name = "krypted.com"
dhcp:subnet_defaults:logVerbosityList:_array_index:0 = "LOW"
dhcp:subnet_defaults:logVerbosityList:_array_index:1 = "MEDIUM"
dhcp:subnet_defaults:logVerbosityList:_array_index:2 = "HIGH"
dhcp:subnet_defaults:dhcp_domain_name_server:_array_index:0 = "8.8.8.8"
dhcp:subnet_defaults:dhcp_domain_name_server:_array_index:1 = "4.4.4.4"
dhcp:subnet_defaults:selected_port_key = "en0"
dhcp:subnet_defaults:selected_port_key_list:_array_index:0 = "en0"
dhcp:subnet_defaults:selected_port_key_list:_array_index:1 = "bridge0"
dhcp:logging_level = "MEDIUM"


Next, we’ll setup a Synology NAS using the instructions found here:

Basic Synology NAS Setup

 Once you’ve setup your Synology NAS, you can install a dhcp server on it, if you need to provide those services. To get started, first open Control Panel and then find DHCP Server in the Control Panel sidebar. 


From here, click on the LAN port.

Because DHCP requires a subnet mask, and a pool of IP addresses that can be shared, the “Enable DHCP server” button will initially be greyed out. Click on the Edit button to define these.

Click on the checkbox for “Enable DHCP server” and enter the following settings:
  • Address lease time: The number of seconds the lease will be valid.
  • Primary DNS: The first DNS server provided to client computers.
  • Secondary DNS: The second DNS server provided to client computers.
  • Domain name: The automatic suffix applied to hostnames of clients (e.g. if you enter Synology in a web browser and this setting was krypted.com then you would be routed to Synology.krypted.com. 
  • Enable Web Proxy Automatic Discovery: provide a PAC file (using DHCP options)
  • URL: The PAC file.
  • Subnetlist: Here you add subnets, which we’ll describe next.

At the Create DHCP Subnet screen, you’ll be prompted for the following fields:

  • Start IP address: The first IP address in the pool that will be handed out.
  • End IP address: The last IP address in the pool that will be handed out (note that in my example, I’m handing out 192.168.55.40 to 192.168.55.50, so 11 addresses – make sure these don’t overlap with other devices that are already using addresses or with other DHCP pools or you will have sporadic device connectivity for some devices).
  • Netmask: The subnet mask to be given to devices along with their lease.
  • Gateway: The default gateway, or router for the network.
  • DHCP Options: I cover these in http://krypted.com/mac-os-x/replace-macos-server-dhcp-service-built-macos-dhcp-service/, but this list includes those supported on the Synology. 

Once your settings are configured, click Create. You’ll then see your pool configured. Click the OK button.

You’ll then see a list of subnets and settings. Click “Enable DHCP server” to start the service. 

Once started, click “Disable DHCP server” to stop the service or go back to the edit screen and click on the DHCP Clients tab to see what IP each client has been provided.

March 21st, 2018

Posted In: Mac OS X, Mac OS X Server

Tags: , , , , ,

Export macOS Server Data
We’re not going to import this, as it only takes a few seconds to configure new settings. Additionally, if you have outstanding services built on macOS Server, you might be able to pull this off without touching client systems. First, let’s grab  which protocols are enabled, running the following from Terminal:

sudo serveradmin settings vpn:Servers:com.apple.ppp.pptp:enabled

sudo serveradmin settings vpn:Servers:com.apple.ppp.l2tp:enabled

Next, we’ll get the the IP ranges used so we can mimic those (or change them) in the new service:

sudo serveradmin settings vpn:Servers:com.apple.ppp.pptp:IPv4:DestAddressRanges

Now let’s grab the DNS servers handed out so those can be recreated:

sudo serveradmin settings vpn:Servers:com.apple.ppp.pptp:DNS:OfferedServerAddresses:_array_index
sudo serveradmin settings vpn:Servers:com.apple.ppp.l2tp:DNS:OfferedServerAddresses:_array_index

Finally, if you’re using L2TP, let’s grab the shared secret:

sudo serveradmin settings vpn:Servers:com.apple.ppp.l2tp:L2TP:IPSecSharedSecretValue

Once we have all of this information, we can configure the new server using the same settings. At this point, you can decide whether you want to dismantle the old server and setup a new one on the same IP address, or whether you’d rather just change your port forwards on your router/firewall.

Ports

Before we configure any VPN services, let’s talk about ports. The following ports need to be opened per The Official iVPN Help Docs (these are likely already open if you’re using a macOS Server to provide VPN services):
  • PPTP: TCP port 1723
  • L2TP: UDP ports 1701, 4500 and 500
  • Enable VPN pass-through on the firewall of the server and client if needed

openvpn
There are a number of ways to get a VPN Server installed on macOS. One would be to install openvpn:

sudo port -v install openvpn2

OpenVPN has a lot of sweet options, which you can read about at openvpn.net.

SoftEther
One of the other tools Apple mentioned is SoftEther. I decided not to cover it here because it uses Wine. And I’m not a fan of Wine. 

Or Use iVPN

That will require some work to get dependencies and some working with files and network settings. Another option would be to install iVPN from here, on the Mac App Store. You can install it manually as well, and if you do, you’ll need to pay separately through PayPal, which is what we’ll cover here.

Once installed, if you purchased the license separately, use the Enter Manually button to provide it.

At the Registration screen, make sure the name, email, and serial are entered exactly as you see them in the email you received.

At the Thank You screen, click OK.

At the EULA screen, click Accept assuming you accept the license agreement.

Configure iVPN
At the main screen, you’ll have a few options, which we’ll unpack here:
  • Use Directory Server: Allows you to use an LDAP or Active Directory connection to provide username and passwords to the service.
  • Use custom accounts: Allows you to manually enter accounts to provide username and passwords for clients to connect to the 
  • Shared Secret: The secret, or a second factor used with L2TP connection.
  • Allow 40-bit encryption keys: Allows clients to use lower levels of encryption. Let’s not do this.
  • IP Address Range: The beginning and ending IP that will be manually handed out to client computers. When configuring the range, take care not to enter a range of addresses in use by any other DHCP services on your network or you will end up with conflicts.
  • Basic DNS: Allows you to configure a primary and second DNS server to send to clients via DHCP when they connect to the VPN interface.
  • Advanced DNS: Allows you to configure DNS servers as well as Search Domains.
  • Configure Static Routes: Allows you to specify the interface and netmask used to access a given IP.
  • Export Configuration Profile: Exports a configuration profile. When imported into a Mac or iOS device, that profile automatically configures the connection to the PPTP or L2TP service you’ve setup.
  • VPN Host Name: Used for the configuration profile so a client system can easily find the server w

If you configure Directory Authentication, you’ll get prompted that it might be buggy. Click OK here.

The Directory Authentication screen allows you to choose which directory services to make available to PPTP or L2TP. If the system hasn’t been authenticated to a directory server, do so using the Users & Groups” System Preference pane.

Once you’ve chosen your directory service configuration, if you require a third DNS server, click on Advanced DNS and then enter it, or any necessary search-domains. Click Done when you’re finished.

Click the log button in the upper left-hand side to see the logs for the service. This is super-helpful when you start troubleshooting client connections or if the daemon stops for no good reason (other than the fact that you’re still running a VPN service on macOS Server and so the socket can’t bind to the appropriate network port).

Finally, you can also create a static route. Static routing provides a manually-configured routing entry, rather than information from a dynamic routing traffic, which means you can fix issues where a client can’t access a given IP because it’s using an incorrect network interface to access an IP.

Once everything is configure, let’s enter the publicly accessible IP address or DNS name of the server. Client computers that install the profile will then have their connection to the server automatically configured and will be able to test the connection.

Configure Clients
If you configured the new server exactly as the old one and just forwarded ports to the new host, you might not have to do anything, assuming you’re using the same username and password store (like a directory service) on the back-end. If you didn’t, you can setup new interfaces with a profile. If you pushed out an old profile to configure those, I’d recommend removing it first if any settings need to change. To configure clients, we’ll install the new profile. When you open the profile on a client system (just double-click it to open it), you’ll see the Install dialog box. Here, click on Continue. 

Because the profile isn’t signed, you’ll then get prompted again (note: you can sign the profile using another tool, like an MDM or Apple Configurator). Click Continue.

Then enter the username that will be used to connect to the VPN and click the Install button.

The Profile can then be viewed and manually removed if needed. 

Click on the new iVPN entry in the Network System Preference pane. Here, you can enable 

Now that it’s easy, let’s click the VPN icon in the menu bar and then click on Connect iVPN to test the connection.

Once clients can connect, you can use the iVPN icon in the menu bar to monitor the status of clients.

March 14th, 2018

Posted In: Mac OS X, Mac OS X Server, Mac Security

Tags: , , , , , , ,

In an earlier article, I mentioned that MAMP Pro was still the best native GUI for managing web services on the Mac, now that macOS Server will no longer serve up those patchy services. After we cover the management in this article, you’ll likely understand why it comes it at $59. 

So you’ve installed MAMP. And you need more than the few basic buttons available there. So MAMP Pro came with it and you can try it for a couple of weeks for free. When you open MAMP Pro, you’ll see a screen where you can perform a number of management tasks. This is a more traditional side-bar-driven screen that will look like what Server Admin might have looked like before the web services screen got simplified in macOS Server.

The Hosts item in SETTINGS will show you each host installed on the server. Think of a host as a site. Each web server can serve up a virtually unlimited number of websites. You can configure an IP binding to the site, or hav
 
If you click on the plus sign, you can add a site. In this example, I’ll add www.krypted.com and then click on create. When doing so, you can configure a database for each site (e.g. if you’re doing multi-tenant hosting), build a site off a template, or select a root directory for the site. 



The Apache tab of each host allows you to configure host-specific settings, including enabling options for directives such as Indexes, Includes, SymLink following, and CGI. More options than were in macOS Server for sure. You can also order allows, allow overrides, add new directives, set the index (or the default page of each site), add additional virtualhosts (such as krypted.com for www.krypted.com), and add a server admin email address. 

These were Apache-centric settings for each host. Click on the Nginx tab if you’re using Nginx instead of Apache. Nginx is a bit less “patchy” so there are a fewer options here. But they’re similar: Configure an index, add parameters, and a feature not available in the GUI options for Apache: allow or deny access based on IP.
 
The SSL tab allows you to generate a CSR, upload the cert and key file, and force connections to use https.

The Extras tab allows you to automatically install standard web packages. For example, here we’ll select WordPress.

Click on the Databases tab. To connect a site to a database, enter the name of the database when prompted. Note: the site itself will need credentials in order to connect, and if you’ve setup an “Extra” in the above step, the database will automatically be configured.

Next, let’s configure the ports used by the web servers. The previous settings were per-site. The rest that we cover in this article will be per-server, as these are global settings applied to the daemons themselves. Each of those services will have a port or ports associated with them. For example, the standard web port used is 80 or 443 for SSL-based connections and the standard port for MySQL is 3306. For publicly-facing sites these would be the standard ports, and given how common they are, there’s a button for “Set ports to 80, 81, 443, 7443, 3306”. Otherwise, you can enter each independently. Because the attaching of daemons is done here, this is also where you configure the user that services run as, as well as when to start the services and truncate log files.

The Editor option configures how the editor appears, which we’ll cover last in this article. The Editing option manages how the editor works (e.g. things  like tabs, autocompletes, etc.

The Fonts & Colors tab allows you to select each color assigned to various types of text.  

The Default Apps tab allows you to configure which app is opened when opening each type of file supported. 

Again, we’ll look at the editor later in this article. First, let’s finish getting the web server setup. Click on Apache. Here, you can load new Apache mods you download from the interwebs. I should mention that an important security step in locking down a publicly-facing web server is to disable all of the mods you don’t absolutely need. 

At the bottom of this screen, there’s also a handle little link to the directory with your logs, so you can read through them if needed.

The Nginx option underneath is similar. Access to log files is there, as is the ability to enable installed Nginx mods. 

The MySQL option also provides access to some straight-forward command-line options, but in a nice GUI. Here, you can configure a root password for MySQL ( which does this: Reset A Lost MySQL Password ), enable phpMyAdmin, MySQL Workbench, and Sequel Pro-based administration, enable network access to the MySQL Service (using ports configured in the Ports section of the app) which I cover at Allow Remote Connections To MySQL, and view logs.

The Dynamic DNS options are cool. Click there, and if your web server is behind a DHCP address, you can configure a dynamic DNS service including DNS-O-Matic, no-ip.com, dyn.com, easydns.com, etc. This way when you reboot and get a new IP address from your ISP, it’ll update the service automatically.

Memcached is a distributed memory object caching system. It’s used to make sites appear faster or to distribute caching between servers for systems that, for example, get clustered. It’s included here for a reason, I’m sure of it! Either way, I actually use it for a few things and like the fact that it’s there. To enable, simply choose how much memory to give it, configure the logging level (usually low unless you’re troubleshooting), and gain access to logs. If you check the “Include Memcached server in GroupStart” then memcache will fire up when you start your web services.

Click postfix. Here, you configure your server to route mail through an email account. If you run this from the command line, you can also configure your server to be a mail server; however, when you do that you’re likely to get mail bouncing all over the place. So if the server or a service on the server is supposed to send mail, it’s usually best to route through something like a gmail account. 

The Languages section allows you to configure how PHP, Python, Perl, and Ruby work on the server. For PHP, you can configure which version of PHP is installed, configure a version of PHP for hosts, enable caching (different than memcached), enable a few basic extensions (I’ve been playing with oauth a lot recently), choose logging options, and have a simple way to see the logs. 

Since you’re running on a Mac, you already have Python, but if you click on the Python option, you can make the version of Python bundled with Mac is 2.7.10 instead of 2.7.13.

Click on Perl to do the same.

Click on Ruby to do the same.

The editor is also pretty easy to use. Simply use the plus sign to add a file you’d like to edit. Keep in mind when browsing that everything MAMP Pro needs is self-contained in the /Applications/MAMP directory, so it should be pretty easy to find files for editing. 

And that’s it. This seems like a lot of stuff, but between sites like ServerFault and other Apache/Nginx articles, you’ll likely find most of the things you need. It’s worth mentioning that I consider this another baby step to just managing Apache using config files. macOS Server tried hard to reduce the complexity of where different settings and options are derived from; MAMP Pro makes no allusion that web server management should be so simple. That’s one of the things I like about it. It’s like you went from riding in a buggy on the back of a bike to riding with training wheels. The more you know, the better off you are.

March 10th, 2018

Posted In: Mac OS X, Mac OS X Server, Mac Security, WordPress

Tags: , , , , , , , , , , ,

Migrating from macOS Mail Server is going to be one of the stranger migrations you might do. Why? Unless you’re moving to basically a custom build of the same tools used in macOS Server (which you’d do by forklifting /Library/Server/Mail/ into a postfix environment and putting the various components Apple changed at compile-time back together), the process for moving to a modern system is going to rely on IMAP and look a little like this:
  • Get a list of accounts
  • Provide the password for each account
  • Setup an initial sync of mailbox contents
  • Look for errors
  • On the day that you cut MX records, do another sync
  • On the day that you cut MX records, migrate local accounts
  • Do a final sync
  • Archive the spam account
  • Take the server offline
You can do this with less effort (e.g. users need to backup their mailboxes, do the sync once, etc), but in my experience the above process has produced the best result for the consumers of mail services and for customers of various types of consultancies. The technical portion of this is pretty straight forward if you follow these steps. The part I like the least is the fact that whosoever has access to those passwords has access to mailboxes, and your actions during that time are very much open to interpretation.

Let’s start by looking at the domains running on the mail server. We’ll do this with serveradmin, by looking at the settings of the mail:postfix:domains:_array_index:

sudo /Applications/Server.app/Contents/ServerRoot/usr/sbin/serveradmin settings mail:postfix:domains:_array_index:

The return will list all of the domains running on the server:

mail:postfix:domains:_array_index:0:name = "krypted.com"

mail:postfix:domains:_array_index:1:name = "kryptedadmin.com"

The primary domain, or the one in _array_index:0 should map to the mydomain variable in /Library/Server/Mail/Config/postfix/main.cf. All of the users will be stored in /Library/Server/Mail/Config/postfix/virtual_users. To see them, simply cat that file:

cat /Library/Server/Mail/Config/postfix/virtual_users

Which would return a line similar to this one for each email account:

charles.edge@krypted.com charles.edge

To just see a list of email address, you could run:

sudo cat /Library/Server/Mail/Config/postfix/virtual_users | grep -E -o "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b"

Now that you have a list of email address, you can easily put them into a file that will sync mailboxes. There are a number of tools you could use to migrate actual mail. These include:
Now, let’s look at using imapsync to actually sync a mailbox. In the most basic form, you could just do:

imapsync --host1 oldmail.krypted.com --user1 charles.edge --password1 mypassword --host2 newmail.krypted.com --user2 charles.edge --password2 mynewpassword

For a small set of users you could easily just paste this command into a .sh file, and run it then run it again the night of the sync, and then run a cleanup a couple of days later in case there were any stragglers. This isn’t going to work for everyone. A lot of people will use custom settings in mail apps. If necessary, you can also configure ports for both servers with –port1 and –port2. You can also configure SSL, synchrinization options, regular expression conversions on objects during the migration, include and exclude items with mail folders, move passwords into a file, etc. Before doing the sync, I’d recommend syncing a test mailbox and reading the entire manpage at https://github.com/imapsync/imapsync.

Changing MX and getting mail to actually flow to the new servers is just a matter of making sure there’s an A Record for the new mail server and putting the MX to that. I recommend setting the TTL of your dns records for mail servers as low as your DNS server or registrar will allow until the migration process is complete. The reason for this is that you want to keep the time frame that mail could flow to both servers at a minimum. The final sync is because DNS changes aren’t instant. Some DNS servers get a lot of traffic and so don’t respect the TTL for a given record. Therefore, that final sync pulls everything that might have accidentally been flowing into your old server into your new server. 

Next, you’ll need to change the host name of the mail server in mail clients and hopefully have users reset their passwords so you don’t have access to their mail any longer. For this, I recommend pushing a profile (e.g. using an MDM or command line equivalent). 

I have seen a number of environments (and helped in some cases) get really crafty. They might present a user with a forced “change password” dialog and then have that stored in a file that admins can’t access. It’s in clear text and there’s always risk. But this allows for non repudiation. It also means that when you send a profile to a device you can have the new account show up and work without the user having to enter a password. Every time users have to touch something, there’s the chance it will get mistyped (I typo things all the time) and there’s a chance that they’ll be confused and call you, so the larger the user base you’re migrating, the more logic you’ll hopefully be able to apply to this process to help keep your phone from ringing. I’ve also seen environments where admins had users type in the password, monitor the sync, and then proceed using client-side scripts. This has always been fraught with peril, but offers an added sense of privacy. 

Don’t forget to grab the mailbox. Seems like this is the main reason I’ve had to revive dead servers. Something got put there and someone needs it… Migrating that mailbox the same as you would any other is a good idea, just-in-case. If you don’t know your quarantine address, run the following to find it:

sudo serveradmin settings mail:postfix:spam_quarantine

Once you’re sure that no mail is flowing to the old server (72 hours is usually a good time frame), you can pull the old server offline. I recommend keeping the server or a clone of the server forever. I’ve needed to revive them here and there due to a variety of reasons that have nothing to do with data integrity of what was migrated. You never know. And if you’re a consultant, there’s no easier way to get fired than to go mucking about with access to mail without a lot of communication in advance. 

Overall, this process can be pretty seamless to your users. But it requires more labor on your side. To keep costs and effort down for you, you could type up a document that steps people through things, but I prefer people at work liking me, so wouldn’t do that personally. Good luck and please comment here if you have further tools or workflows that you prefer!

February 15th, 2018

Posted In: Mac OS X Server

Tags: , , ,

“Taking a new step, uttering a new word, is what people fear most.” ― Fyodor Dostoyevsky, Crime and Punishment

The Apple Wiki Server is sadly going away. I always liked this service. It was thoughtfully designed and looked much nicer than most of the other tools available out there. Sure, you couldn’t write articles offline, write in markdown, or do a lot of other things that I’ve learned to both love and hate from other solutions, but honestly it always felt the most Apple of services in macOS Server because it didn’t have every-single-checkbox. So, I’ll pour a little Jaëger on the ground in memory of the wiki server and then… export some stuffs and move on.

Before we get started, let’s talk about where you’re going to be putting this stuff. You can export in three formats (in order of the likelihood you’ll use them): 
  • wxr: the native WordPress format that can also be used by a variety of other solutions as WordPress is their reference competitor of sorts. WordPress also has wiki plugins, which you could experiment once you’ve imported all of your stuff. ExpressionEngine, Drupal, and many other solutions support importing via the wxr format. For importing into confluence check out https://wiki.afm.co/display/PUBL/HOW+to+import+Wordpress+into+Confluence which requires you to run your own server temporarily if your ultimate goal is to move to the Atlassian Cloud (which is pretty much what I ended up doing). 
  • pages: A folder that stores static html, rather than the dynamic html files that the wiki services builds. You might use this if you just want to take a permanent archive of the wiki service and maybe hire an intern to cut/copy/paste pages into a new wiki solution, like Confluence. 
  • json: If you’re going to be scripting a custom import into another solution then json is likely to be your best bet. I blame python. There are more modules than I can count to import that assist with manipulating json. If another wiki or documentation tool has an import option, you can find a way to get it in. You’ll likely encounter broken links, etc. Unless you correct those in the script during import. Which is a lot of logic. 
  • legacy: Uses PostgreSQL. Probably not useful for a lot of people. I’ve done some work reverse engineering that database, but it changes routinely and so that work is put out of date at regular intervals.
  • decoded: A more swifty export. I think I’d just use this if I were building a swift app based on my export. Which I can’t imagine doing.

The export command is now built into wikiadmin (unlike a couple of previous articles I wrote where it was a standalone command back in the 10.5 or 10.6 era). So to export, you’ll run wikiadmin followed by the export verb. The next option you’ll provide in the command is either -all or the -name of the wiki (multiple wikis can be provided with  comma separated values) and then the -format you’re exporting into (listed above), and finally the -path of the destination. To put that all together, would look like the following if we’re exporting into WordPress: 

sudo /Applications/Server.app/Contents/ServerRoot/usr/bin/wikiadmin export -name Legal -format wxr -path /exports

Exports will be owned by _teamserver so to get to the data, you’ll have to chmod the files:

sudo chmod -R /exports

Inside that target directory, you’ll see a number of files as you can see in the following screenshot:

So, for wxr there will be a directory called wiki that doesn’t have much in it. And then there will be an xml file for each user that has a “page” as well as another with all the articles in it. You’ll need to look at them, but typically the biggest and last one exported (so the last one in the directory listing) will have all your articles.

Once you have the correct XML file, you can import it! To do so, go to WordPress, hover over tools in the sidebar and click on Import. At the import screen, select the xml file, and then click on the “Upload file and import” button.




Note: If the import fails, you may have to edit your php.ini to increase post_max_size or upload_max_filesize. But once the import is complete, I’d change those back to the defaults.

Now, let’s say instead I was going to json. In the following iteration of the earlier command, I’m going to do -all and then I’m going to do json as the -format:

sudo /Applications/Server.app/Contents/ServerRoot/usr/bin/wikiadmin export -all -format json -path /exports

This output starts as follows (I left off the subsequent articles:

{

  “LongName” : “Legal”,

  “UpdateTime” : “2018-02-09T08:37:41.691-0600”,

  “Description” : “test”,

  “ExportDate” : “2018-02-09 16:06:51 +0000”,

  “Revision” : 1,

  “UpdatedByLogin” : “charles.edge”,

  “BlogPosts” : [

  ],

  “Theme” : “carbon,,”,

  “WikiUID” : “c7de0acb-baae-baae-e9bd-f78d3e4d43ed”,

  “ShortName” : “legal”,

  “Pages” : [

{

  “LongName” : “test page 1”,

  “UpdateTime” : “2018-02-09T08:38:32.025-0600”,

  “UpdatedByLogin” : “charles.edge”,

  “Revision” : 3,

  “PageTextValue” : “To edit this page, click the Edit (pencil) button. To delete this page, click the Action (gear) button and choose Delete. When you edit this page, you can easily rename the page, and use the editing toolbar to: Apply paragraph or character styles to text. Create bulleted lists, numbered lists, and tables. Insert media, such as images, audio, or QuickTime movies. Attach files. Insert an HTML snippet from another website or email. For more information about editing pages, click the Action (gear) button and choose Help. 1 1”,

  “TinyID” : “x4j836N4C”,

  “Tags” : [

” test”,

“wtf”

  ],

  “CreateTime” : “2018-02-09T08:38:07.039-0600”,

  “RelatedItems” : [

{

  “LongName” : “Legal”,

  “UID” : “c7de0acb-baae-baae-c6c2-aae392690186”

}

  ],

  “CreatedByLogin” : “charles.edge”,

  “RenderedPage” : “<div id=\”text-block-view-24c701f8-0e15-49a7-b331-f8b755cb6a32\” class=\”block wrapchrome text\” data-guid=\”24c701f8-0e15-49a7-b331-f8b755cb6a32\” data-type=\”text\” contenteditable=\”false\”><div id=\”text-block-view-24c701f8-0e15-49a7-b331-f8b755cb6a32-wrapper\” class=\”wrapper wrapchrome\”><div id=\”text-block-view-24c701f8-0e15-49a7-b331-f8b755cb6a32-inner\” class=\”inner wrapchrome\”><div class=\”content selectable wrapchrome\”><div id=\”text-block-view-24c701f8-0e15-49a7-b331-f8b755cb6a32-editable\” class=\”editable wrapchrome\”><p>To edit this page, click the Edit (pencil) button. To delete this page, click the Action (gear) button and choose Delete.<\/p><p>When you edit this page, you can easily rename the page, and use the editing toolbar to:<\/p><ul><li>Apply paragraph or character styles to text.<\/li><li>Create bulleted lists, numbered lists, and tables.<\/li><li>Insert media, such as images, audio, or QuickTime movies.<\/li><li>Attach files.<\/li><li>Insert an HTML snippet from another website or email.<\/li><\/ul><p>For more information about editing pages, click the Action (gear) button and choose Help. 1 1<\/p><\/div><\/div><\/div><\/div><\/div>”,

  “RevisionHistory” : [

{

  “ChangedByLogin” : “charles.edge”,

  “Version” : 1,

  “PageTextValue” : “”,

  “RenderedPage” : “<div class=\”block text\”><div class=\”content\”><div class=\”editable\”><p>To edit this page, click the Edit (pencil) button. To delete this page, click the Action (gear) button and choose Delete.<\/p><p>When you edit this page, you can easily rename the page, and use the editing toolbar to:<\/p><ul><li>Apply paragraph or character styles to text.<\/li><li>Create bulleted lists, numbered lists, and tables.<\/li><li>Insert media, such as images, audio, or QuickTime movies.<\/li><li>Attach files.<\/li><li>Insert an HTML snippet from another website or email.<\/li><\/ul><p>For more information about editing pages, click the Action (gear) button and choose Help.<\/p><\/div><\/div><\/div>”,

  “ChangeType” : “create”,

  “ChangeTime” : “2018-02-09T08:38:07.039-0600”

},

{

  “ChangedByLogin” : “charles.edge”,

  “Version” : 2,

  “PageTextValue” : “To edit this page, click the Edit (pencil) button. To delete this page, click the Action (gear) button and choose Delete. When you edit this page, you can easily rename the page, and use the editing toolbar to: Apply paragraph or character styles to text. Create bulleted lists, numbered lists, and tables. Insert media, such as images, audio, or QuickTime movies. Attach files. Insert an HTML snippet from another website or email. For more information about editing pages, click the Action (gear) button and choose Help. 1”,

  “RenderedPage” : “<div id=\”text-block-view-24c701f8-0e15-49a7-b331-f8b755cb6a32\” class=\”block wrapchrome text\” data-guid=\”24c701f8-0e15-49a7-b331-f8b755cb6a32\” data-type=\”text\” contenteditable=\”false\”><div id=\”text-block-view-24c701f8-0e15-49a7-b331-f8b755cb6a32-wrapper\” class=\”wrapper wrapchrome\”><div id=\”text-block-view-24c701f8-0e15-49a7-b331-f8b755cb6a32-inner\” class=\”inner wrapchrome\”><div class=\”content selectable wrapchrome\”><div id=\”text-block-view-24c701f8-0e15-49a7-b331-f8b755cb6a32-editable\” class=\”editable wrapchrome\”><p>To edit this page, click the Edit (pencil) button. To delete this page, click the Action (gear) button and choose Delete.<\/p><p>When you edit this page, you can easily rename the page, and use the editing toolbar to:<\/p><ul><li>Apply paragraph or character styles to text.<\/li><li>Create bulleted lists, numbered lists, and tables.<\/li><li>Insert media, such as images, audio, or QuickTime movies.<\/li><li>Attach files.<\/li><li>Insert an HTML snippet from another website or email.<\/li><\/ul><p>For more information about editing pages, click the Action (gear) button and choose Help. 1<\/p><\/div><\/div><\/div><\/div><\/div>”,

  “ChangeType” : “edit”,

  “ChangeTime” : “2018-02-09T08:38:26.194-0600”

},

There’s a glaring omission in this article: files. I’ll get to that later in another article. But the gist is that you can do a webdav and move them, but you kinda’ break any links…

Finally, if I came up short in this article (as I often do), the official wikiadmin man page: 

wikiadmin export -name somewiki,anotherwiki -path /var/tmp/two-exported-wikis

wikiadmin import -all -path /var/tmp/two-exported-wikis

wikiadmin import -all -path /var/tmp/two-exported-wikis/Exported.wikis

wikiadmin export -all -format json -path /var/tmp/readable-wikis

wikiadmin export -all -format pages -path /var/tmp/browsable-wikis

wikiadmin export -all -format wxr -path /var/tmp/wxr-wiki-files

wikiadmin migrate -r /Volumes/SnowLeopard/Library/Collaboration

RETURN VALUES

wikiadmin returns a status code of 0 for success. In the event of failure it returns a non-zero status, and writes error messages to stderr.

FILES

/Library/Server/Wiki/Logs/wikiadmin.log

Log file for wikiadmin activity

/Library/Server/Wiki/Logs/collabd.log

Log file for Wiki http server activity

/Library/Server/Wiki/, /tmp/, /var/tmp, /Users/Shared

Folders readable and writable by user _teamsserver where exports can typically be placed

<export-path>/Exported.wikis

The name of the bundle created when exporting wikis for formats other than pages.

<export-path>/FileData/*/*/*

For -format pages – exported files that were uploaded to the wiki as files or embedded in pages

<export-path>/wiki/projects/*/*.html

For -format pages – exported wiki main pages and user profile pages

<export-path>/wiki/pages/*/*.html

For -format pages – exported wiki pages

<export-path>/css/*.css

For -format pages – style sheets for use in browsing the exported content

<export-path>/index.html

For -format pages – a generated landing page with links to all exported wikis and pages

HISTORY

The wikiadmin command first allowed export in macOS Server 3.2. The packaging format for exported wikis was revised with macOS Server 4.1, but the

new wikiadmin still supports importing from the older export formats.

macOS Server March 30, 2017 macOS Server

February 8th, 2018

Posted In: Mac OS X, Mac OS X Server

Tags: , , , , ,

Next Page »