Fix broken SSH key based authentication on OS X El Capitan

A fresh OS X El Capitan 10.11.3 install on my new Hackintosh broke my well working SSH key based authentication (passwordless). I wasn’t able to connect from a remote systen to my OS X system without getting asked for the password. Before this I created a key based login to the OS X system without any negative feedback. So what the hell is wrong?

To figure out the problem I debugged SSH with the -v option on the remote where I tried to connect to my Hackintosh.

ssh -v USERNAME@example.com

Between all the debug messages I found a very useful information:

debug1: Remote: Ignored authorized keys: bad ownership or modes for directory /Users/USERNAME

Well, this line tells enough. I had to fix the permissions of the /Users/USERNAME folder.

chmod 700 /Users/USERNAME

chmod 700 grants full permissions to the owner, but group and others cannot access it. That’s fine!
Problem solved for me :-)

Disable PHP notice logging

The default PHP configuration reports all errors and also notices, this could blow up the logs very fast. If you want to log only errors instead of all, including notices, you have to edit the php.ini.

Where is the php.ini configuration file located? PHP delivers us all configuration details with the phpinfo(); function, you’ll find the path to your php.ini using this function.

You could also run this command in your console, but beware: If you are using PHP-FPM your php.ini is stored on a different location.
To find the php.ini with PHP-FPM run this command:

/usr/sbin/php5-fpm -i | grep php.ini

This will give you:

Configuration File (php.ini) Path => /etc/php5/fpm
Loaded Configuration File => /etc/php5/fpm/php.ini

With a default PHP setup:

php -r "phpinfo(INFO_GENERAL);" | grep php.ini

You are using PHP only with your webserver? Simply create a new php file with this content:

<?php phpinfo(INFO_GENERAL); ?>

… and request it in your browser. Search for php.ini and you’ll find the correct path.

Now it’s time to edit the php.ini, in my case the configuration is inside /etc/php5/fpm/php.ini.

nano /etc/php5/fpm/php.ini

Default PHP configuration (try CTRL + W to search with nano for error_reporting, it’s a big config!):

error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

New configuration:

error_reporting = E_COMPILE_ERROR|E_ERROR|E_CORE_ERROR

Finally restart your webserver or only the php5-fpm process, depends on what you are using:

  • Apache 2: /etc/init.d/apache2 restart
  • nginx: /etc/init.d/nginx restart
  • PHP-FPM: /etc/init.d/php5-fpm restart

nginx/Apache: force the browser to show a file instead of downloading

Linking to a text file could force the browser to download the file instead of parsing the files content to the browser window.

With nginx and Apache it’s easy to force the browser to show the content directly, this could be very useful. The trick is to add the text/plain content-type.

The examples below will add Content-Type text/plain to the header for .js, .sh and .txt files.

nginx configuration inside the server { } configuration block:

location ~* ^.+\.(js|sh|txt)$ {
	add_header Content-Type text/plain;
}

Apache requires mod_mime (should be installed/activated by default!). You could add this line to your .htaccess or in the httpd.conf:

AddType text/plain .js .sh .txt

How to enable Cross-Origin Requests (CORS) on nginx

Requesting files from a different host could cause problems because of Cross-Origin Resource Sharing (CORS) polices:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://cdn.example.com/fonts/fontawesome-webfont.woff. This can be fixed by moving the resource to the same domain or enabling CORS.

Cross-domain requests would otherwise be forbidden by a lot of web browsers, because of the same-origin security policy.
Because there are some browsers which ignore the same-origin security policy, you should enable CORS on nginx if you host content on a different domain or subdomain. Otherwise the client can’t load the requested files.

In my case Safari ignores the same-origin security policy if the file is on the same domain, but on a different subdomain – Firefox takes care of the policy and blocks the request – and the client isn’t able to load the file. This could change from version to version. So it’s recommend to enable cross-origin requests!

To enable CORS you have to modify the nginx config file with your server block configuration which serves the external files.

Just place a add_header option inside location to your server block:

location / {
	add_header 'Access-Control-Allow-Origin' *;
}

In my example I use a wildcard to allow every requests. We could restrict the access instead of using a wildcard by changing it to http://www.example.com.

To enable CORS only for *.example.com you should use this:

location / {
	if ($http_origin ~* (https?://[^/]*\.example\.com(:[0-9]+)?)) {
		add_header 'Access-Control-Allow-Origin' "$http_origin";
	}
}

Multiple domains with enabled cross-origin requests are also able:

location / {
	if ($http_origin ~* (https?://[^/]*\.example\.com(:[0-9]+)?|https?://[^/]*\.otherdomain\.com(:[0-9]+)?)) {
		add_header 'Access-Control-Allow-Origin' "$http_origin";
	}
}

Finally reload nginx (Debian: /etc/init.d/nginx reload) and test it. Have a look on the header response – Firebug helps – (Maybe you have to clear your browser cache!):

Firebug - CORS Request on nginx

Or something like this:

HTTP/1.1 200 OK
...
Access-Control-Allow-Origin: *
...

Enable IPv6 on Debian Wheezy

Because I have to use IPv6 I checked all my servers with ping6 <ipv6>. One of them didn’t respond, but the server was online. Ping the IPv4 just worked. So I checked the network settings on the machine (Debian Wheezy 7.5, default OVH setup) with ifconfig and I missed the inet6 entry in my ifconfig output.

First I checked the config file for my network interfaces (/etc/network/interfaces) and I found no problems with the configuration.

Well, I had a look at /proc/sys/net/ipv6/conf/eth0/disable_ipv6 and it shows me, that IPv6 is currently disabled:

cat /proc/sys/net/ipv6/conf/eth0/disable_ipv6

Output must be 0, but it was 1!

I figured out that my system has disabled IPv6 because of an entry inside /etc/sysctl.d/disableipv6.conf.
After I changed the value for net.ipv6.conf.all.disable_ipv6 from 1 to 0 I finally got my IPv6 working after a restart.

nano /etc/sysctl.d/disableipv6.conf
net.ipv6.conf.all.disable_ipv6=0

Don’t know why IPv6 was disabled automatically on this system, but now it works very well.

nginx: fix 502 gateway error with fastcgi_buffers

Keep an eye on your logs can help you to prevent and fix the 502 gateway error on nginx. Typically the values for fastcgi_buffers and fastcgi_buffer_size are too low and you’ll get very fast a 502 error on a new nginx setup.

Typical error for to low values:

[error] 1375#0: *325 upstream sent too big header while reading response header from upstream...

I check my logs regularly, specially on new project/sites, with awk to get the best values for my nginx configs.

Let’s get the maximum response size:

awk '($9 ~ /200/)' access.log  | awk '{print $10}' | sort -nr | head -n 1

And now the average response size from the logfile:

echo $(( `awk '($9 ~ /200/)' access.log | awk '{print $10}' | awk '{s+=$1} END {print s}'` / `awk '($9 ~ /200/)' access.log  | wc -l` ))

My results for cribbl.com are max. 3435209 bytes (3.28 MB!) and 14746 bytes average.

Now i modify my nginx.conf inside the http { } section if you want a global solution, otherwise move it to your server { } section.

http {
	fastcgi_buffer_size 128k;
	fastcgi_buffers 16 256k; // 4 MB

	...
}

The fastcgi_buffers setting grants additional buffers based on chunks, to hold max response in the memory.

Install Debian on SD card for Raspberry Pi with Mac OS X

It’s really easy to use the terminal to install Debian on SD Card for Raspberry Pi with Mac OS X. This method works great and also much better than these AppleScript programs which are asking for your password.

Download latest Debian Raspbian image

Get the latest Raspbian imagen (currently Debian Wheezy 7.5) with your browser from http://www.raspberrypi.org/downloads or directly with curl from your terminal:

cd ~/Downloads/
curl -L http://downloads.raspberrypi.org/raspbian_latest -o raspbian_latest.zip

When the download is complete it’s safer to compare the the SHA-1 checksum with the one on the downloads page:

shasum raspbian_latest.zip

If the checksum matches you can finally unzip the image:

unzip raspbian_latest.zip

Install Raspbian on your SD card

Insert your SD card in your Mac or any SD card reader attached to your Mac, open the terminal and run this:

diskutil list

Now we have to find our SD card. Watch for the correct size or the name and please don’t use your system hard drive!
I use a 16 GB SD card, so I have to take the 15.9 Gi entry which has the name (mount name) NO NAME. It’s the /dev/disk3s1 identifier entry.

/dev/disk0
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *121.3 GB   disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:          Apple_CoreStorage                         121.0 GB   disk0s2
   3:                 Apple_Boot Boot OS X               134.2 MB   disk0s3
/dev/disk1
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *1.0 TB     disk1
   1:                        EFI EFI                     209.7 MB   disk1s1
   2:          Apple_CoreStorage                         999.3 GB   disk1s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk1s3
/dev/disk2
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:                  Apple_HFS Macintosh HD           *1.1 TB     disk2
/dev/disk3
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *15.9 GB    disk3
   1:                 DOS_FAT_32 NO NAME                 15.9 GB    disk3s1

You have to unmount this card (remove the “s1” from /dev/disk3s1):

diskutil unmountDisk /dev/disk3
$ Unmount of all volumes on disk3 was successful

Use dd to copy the image on your SD card:

  • You could drag & drop the .img file directly behind sudo df if= to get the correct path
  • Use the same device as used with diskutil unmountDisk
sudo dd if=~/Downloads/2014-06-20-wheezy-raspbian.img of=/dev/disk3 bs=1m

It’s very easy to install Debian on an SD card for a Raspberry Pi, but to copy the image could take really long – depends on the size and performance of the SD card and from your card reader performance.
dd gives us no output but if you want to check if it’s still running just press CTRL + T.

load: 2.01  cmd: dd 32139 uninterruptible 0.00u 1.56s
201+0 records in
200+0 records out
209715200 bytes transferred in 107.578531 secs (1949415 bytes/sec)

dd finishes without any feedback on success, it’s done when it’s done.

Running mount | grep disk3 shows us the new mount point for your SD card:

mount | grep disk3
/dev/disk3s1 on /Volumes/boot (msdos, local, nodev, nosuid, noowners)

Thats it, your SD card is ready to use in your Raspberry Pi after you run:

diskutil unmountDisk /dev/disk3

Simply put your fresh created Raspbian SD card in your Raspberry Pi and power it up.

I have 2 SD Cards for my Raspberry Pi: One is always in use, the second one has a fresh install, so I don’t have to wait if I want to work on a new system.

SSH login without a password (Linux / Mac OS X)

Enough of entering always the SSH password for an SSH login in your terminal? Follow this fast tutorial to get rid of this problem and enable your SSH login without a password.

On Mac OS X you have to install ssh-copy-id, Linux users should have this already. Simple run the following commands to get it work on your system.

Perhaps you have to create this folder on OS X or some Linux distributions:

mkdir -p /usr/local/bin/

Download the binary from GitHub:

sudo curl https://raw.githubusercontent.com/beautifulcode/ssh-copy-id-for-OSX/master/ssh-copy-id.sh -o /usr/local/bin/ssh-copy-id

Grant access to run the file with the chmod +x:

sudo chmod +x /usr/local/bin/ssh-copy-id

Now it’s time to generate your RSA key-pairs!
Run this command – there is no need to change the location (default: ~/.ssh/id_rsa.pub) and you don’t have to enter a passphrase.

ssh-keygen -t rsa

You will get an output like this:

Generating public/private rsa key pair.
Enter file in which to save the key (/Users/USERNAME/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/USERNAME/.ssh/id_rsa.
Your public key has been saved in /Users/USERNAME/.ssh/id_rsa.pub.
The key fingerprint is:
4b:2f:fa:3a:19:74:24:2b:f1:52:e6:61:ab:53:ce:d3 YOUR_USERNAME@Gorath.local
The key's randomart image is:
+--[ RSA 2048]----+
...
+-----------------+

Finally you have to use the ssh-copy-id command to store your password for the SSH login. Enter your SSH password when you get asked.
Please use your USERNAME and the HOST for the SSH Login (this could be a domain or an IP address). Do you have a different port? 22 is default, at this point you could change it with -p PORTNUMBER.

ssh-copy-id -i ~/.ssh/id_rsa.pub "-p 22 USERNAME@HOST"

Now try to login:

ssh -l USERNAME HOST

Does it work? Congratulations! And by the way, please don’t do this with a root login :-)

×