I have written an application, an automatic VPN provisioning web portal in python for Apple devices.

What bugs me is a difference in behaviour between the testing and production server; the former is using Apache, while the latter is using lighthttpd.

In lighhttpd the .mobileconfigfile is opened and "executed" e.g. it opens SysPrefs automatically, while in Apache that is not happening.

I have already noticed lighhtpd is much more lax concerning proper Content-Type definitions, however the issue at hand is that Safari will load and "auto-execute" .mobileconfig files properly with lighthttpdwhilst the same does not happen with Apache.

What further irks me it that in both servers I have defined properly the corresponding mime.type as in:


$HTTP["url"] =~ "\.mobileconfig$" {
    setenv.add-response-header = ( "Content-Disposition" => "attachment" )
    mimetype.assign = (".mobileconfig" => "application/x-apple-aspen-config",
                    "" => "application/octet-stream")

As in Apache it is:

dovpn.conf (vhost)

AddType application/x-apple-aspen-config .mobileconfig

The first clue of a difference actually seems to stem from that add-response-header directive in lighthttpd.

In the generated HTML, I have:

a download="profile.mobileconfig" href="../upload/8bd16b26-1473-4994-9803-8268a372cd0d.mobileconfig" type="application/octet-stream">Download automatic profile/a

and I do an automatic download of that via Javascript

//If in Safari - download via virtual link click
if (window.downloadFile.isSafari) {
    //Creating new link node.
    var link = document.createElement('a');
    link.href = sUrl;
    if (link.download !== undefined) {
        //Set HTML5 download attribute. This will prevent file from opening if supported.
        var fileName = sUrl.substring(sUrl.lastIndexOf('/') + 1, sUrl.length);
        link.download = fileName;
    //Dispatching click event.
    if (document.createEvent) {
        var e = document.createEvent('MouseEvents');
        e.initEvent('click', true, true);
        return true;

The content of the generate page also only has as Content-Type:

Content-Type: text/html\n\n

both in Apache and lighthttpd. I sniffed over the wire, and there are no apparent changes made to Content-Type made via lighthttpd.

Will I be able to replicate similar functionality of setenv.add-response-header with Apache?

I have already tried to add to the Apache host:

<Files "*.mobileconfig">
      Header set Content-Disposition attachment


SetEnvIf Request_URI "\.mobileconfig$" change_header
Header set Content-Disposition attachment env=change_header


SetEnvIf Request_URI "\.mobileconfig$" change_header
Header always add "Content-Disposition" "attachment" env=change_header


<Files "*.mobileconfig">
    Header append Content-Disposition attachment

I also have tried, in the actual directory, creating an .htaccess file with:

<IfModule mod_headers.c>
    <FilesMatch "\.mobileconfig$">
        ForceType application/octet-stream
        Header append Content-Disposition "attachment"
        Allow from all


<IfModule mod_headers.c>
    <FilesMatch "\.mobileconfig$">
        ForceType application/octet-stream
        Header add Content-Disposition "attachment"
        Allow from all

In both cases, besides attachment, I also used "attachment".

Please note mod_headers is active by default in Apache/Debian 9, and none of these alternatives worked out.

Actually, I just remembered lighthttpd is using HTTP, and Apache HTTPS. I tested it out lighthttpd with HTTPS, and it also works over HTTPS, while Apache does not.

Output of curl -k -I https://localhost/cgi-bin/vpn.py in lighthttpd server:

HTTP/1.1 200 OK
Content type: text/html
Content-Length: 331
Date: Thu, 01 Jun 2017 09:03:26 GMT
Server: lighttpd/1.4.45

Output of curl -k -I https://localhost/cgi-bin/vpn.py in Apache server:

HTTP/1.1 200 OK
Date: Thu, 01 Jun 2017 09:05:25 GMT
Server: Apache
Vary: Accept-Encoding
X-Frame-Options: sameorigin
Content-Type: text/html; charset=UTF-8

Furthermore, in Apache too:

$curl -k -I https://localhost/download/xxx.mobileconfig
HTTP/1.1 200 OK
Date: Thu, 01 Jun 2017 09:13:35 GMT
Server: Apache
Last-Modified: Thu, 01 Jun 2017 03:08:57 GMT
ETag: "1f3b-550dd5b89d8df"
Accept-Ranges: bytes
Content-Length: 7995
X-Frame-Options: sameorigin
Content-Disposition: attachment
Content-Type: application/x-apple-aspen-config

Using Safari->Develop->Show web Inspector->Debugger->clicking on main page->Copy as curl only returns me "curl 'https://xxxx/cgi-bin/vpn.py' -Xnull" when pasting.

I also tried disabling X-Frame-Options: "sameorigin" and it made no difference (I knew it was a long shot)

  • In my experience Content-Type: is the header clients use to determine how to handle the server response, could you add the output of curl -I URL | sort for the two servers to your question? – the_velour_fog Jun 1 '17 at 8:17
  • @the_velour_fog I have posted the curl output, also about the .mobileconfig directory, thanks. – Rui F Ribeiro Jun 1 '17 at 9:15
  • ah, sorry, thats not the response safari will be getting (as curl will be announcing itself as the user agent). are you familar with safari's copy as curl feature? here is an instruction on stackoverflow can you paste a (redacted if needed) post of that output? - instead of the curl, sorry – the_velour_fog Jun 1 '17 at 9:30
  • @the_velour_fog Using Safari->Develop->Show web Inspector->Debugger->clicking on main page->Copy as curl only returns me "curl 'xxxx/cgi-bin/vpn.py' -Xnull" when pasting. e.g. it is not working. However I can assure you I have not configured headers changes for different user agents. – Rui F Ribeiro Jun 1 '17 at 9:51
  • sure. what Im interested to know is what the Content-Type header safari is seeing. and particularly if its application/octet-stream (or similar). its not just the user agent, that matters in the HTTP request headers. there will be possibly a dozen or more headers safari will be sending, which could - or could not - be triggering the deviations between the different server responses. can you check the Content-type that the different servers are returning the in the web inspector tools? – the_velour_fog Jun 1 '17 at 9:52

It seems using the .htaccess file solved the problem of adding to the headers the Content-Disposition.

However, the problem into replicating the functionality and the added complexity in debugging and tests --- seems to have another explanation.

It seems that both in the lastest beta and current version of the Sierra update .mobileconfig files were taken out of the Safari list of "safe" files for opening for security reasons.

I updated yesterday (or the day before yesterday) the MacOS at work, today at home, and I no longer can get .mobileconfig files on either the production or the pre-production system to open automatically.

I just update my iPhone to iOS 10.3.3 beta, and it also seems to confirm the tendency of Apple dealing as .mobileconfig provisioning files as potentially dangerous. Now, when clicking on such a file, you are presented with a new warning:

This website is trying to open Settings to show you a configuration profile. Do you want to allow this?
Ignore - Allow

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.