Snippet : Add Your SSH Public Key To A Distant Server

I think I could cover the ssh login subject in a longer article, for now here is a quick snippet to create and add your public ssh key to your server, so you can login into it without typing your password again (and then disable the password login ability to increase your security) :

  1. Pop-up a Terminal window and generate your ssh key (if needed – don’t erase your existing .id_rsa.pub file if you’re already using it !) :
    ssh-keygen -t rsa -b 4096

    This will generate a 4096 bits RSA key.

    – ssh-keygen will generate a 1024 DSA key ;
    – ssh-keygen -t rsa1 will generate a 1024 RSA key ;
    – ssh-keygen -t rsa will generate a 2048 RSA key.

    The main argument why you could generate a weaker RSA encryption is the power and performance consumption, although it doesn’t really matter for modern machines. Thus this would apply to older servers or when it comes to micro-manage your performances.

  2. In the case you can still login with a login/password couple, type :
    ssh-copy-id username@remote_host

    where, of course, username is the one you want to login with, remote_host is, well, your remote server IP or URL.

  3. That’s it ! Try to login into your server with :
    ssh username@remote_host

    You might be prompted once about the new rsa key being added (client and/or server side console messages, more in a next article), most of the time simply agree if requested to.

Snippet: How To Show Hidden Files on Mac OSX

  1. Pop-up a Terminal (Applications > Terminal, Cmd+Space : “Terminal”)
  2. Paste the line below :
    defaults write com.apple.finder AppleShowAllFiles 1
  3. Reload Finder (Apple logo > Force Quit > Select “Finder” > Reload)
  4. That’s it ! You’ll see (most of) all the hidden files in Finder. Even the not so sexy .DS_Store files that stores the custom attributes of the containing folder, kind of like Thumbs.db on Windows.
  5. To hide them back, simply type into a Terminal :
    defaults write com.apple.finder AppleShowAllFiles 0

Faking PHP version for Composer

Sometimes Composer doesn’t fetch the right PHP version for some reasons : Using Plesk for exemple, or some other server management tool, the way websites are handled is so that multiple websites are into containers with their own configurations.

This way, the “stock” PHP version installed into the server could be one version, but Apache could also run another one, which makes Composer trusting that you’re running under the wrong version :

For example, php-v tells :

tomsihap@vps:~/httpdocs/mywebsite$ php -v
PHP 5.5.9-1ubuntu4.17 (cli) (built: May 19 2016 19:05:57)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
 with the ionCube PHP Loader v4.6.0, Copyright (c) 2002-2014, by ionCube Ltd., and
 with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies

Same server, and into the given “mywebsite” :

Capture d'écran 2016-08-04 15.34.55.png

 

To force Composer to require or acknowledge your PHP version, add into your composer.json file :

"config": { 
   "platform": { 
      "php": "5.6.24"
   },
}

And that’s it, composer update should work.

Lots of thanks to this post !

Plesk : 403 Forbidden after messing around with your Ubuntu/Debian or CentOS server

One of the many reasons why you have a 403 error on your website when using Plesk and tweaking your server (updates for exemple that can modify your Apache2 configuration, it happened to me when installing Landscape) might be that you need to add the APACHE_RUN_USER (usually www-data but make sure by looking for it into /etc/apache2/envvars) into the psaserv group (1).

vim /etc/apache2/envvars
/APACHE_RUN_USER # to be run under Vim
# The /{search} command in Vim is the search command. Note the user, it should be www-data. 
sudo usermod -a -G psaserv www-data # Adding the user back into the psaserv group

Using CentOS, the user must be “apache”.

sudo usermod -a -G psaserv apache

(1) Cannot access website with 403 Forbidden error : You don’t have permission to access / on this server

Easy way to remove “/public” in the URL path in Laravel 5.2

How to remove the /public path from your URL in Laravel 5.2 the easiest way if you can’t or don’t want to modify the Apache document root ?

In a fresh Laravel 5.2 install, the public frontend is located in

 example.com/public/index.php

To remove the /public/ part of your URL, simply copy-paste /public/index.php and /public/.htaccess to /index.php and /.htaccess.

cd your/project/folder
cp public/index.php index.php
cp public/.htaccess .htaccess

And of course, modify the path within index.php :

require __DIR__.'../bootstrap/autoload.php';
and
$app = require_once __DIR__.'../bootstrap/app.php';

becoming :

require __DIR__.'/bootstrap/autoload.php';
and
$app = require_once __DIR__.'/bootstrap/app.php';

This is by far not the best way to do it but the easiest way if you can’t modify your Apache configuration files for examples.

A better way to do it if you have to push it to a production server would be to move all your Laravel files from the project root folder in another place in your server and keep the content of the /public folder in your server root url.

Then, just update the index.php consequently.

How To Install XDebug on MAMP (OSX)

Xdebug is debugger and profiler that will prettify your errors by printing out stack traces in case of errors or exceptions, with a timestamp showing the duration of each step of the stack. There are a lot of benefits to have it activated, even on a production server, even more on your development environment.

Here is how to install Xdebug on a MAMP installation.

First, locate your php.ini : you might be running PHP 5.6 or PHP 7.0.0, either way you’ll have to edit the right configuration files. Take a look at your phpini(), usually at

http://localhost:8888/MAMP/index.php?page=phpinfo

Be careful, the 8888 port may be different to you (use your usual localhost URL). Look for the “Loaded Configuration File” line. Mine is:

/Applications/MAMP/bin/php/php7.0.0/conf/php.ini

Capture d'écran 2016-02-22 10.09.32

Simply edit this file and look for the “[xdebug]” section, usually at the end of the file.

If you want to do it via your Terminal :

$ vim /Applications/MAMP/bin/php/php7.0.0/conf/php.ini

VIM Crash Course

Browse (Command Line Mode)

The editor has many modes: right after you’ve opened the file, you’re in browsing mode. You can navigate threw the file via the arrow keys… or :

H: Left
J: Down
K: Up
L: Down
G: Go to the bottom of the file
gg : Go to the top of the file
/text : Look for the next occurence of “text”,
n : go to the next occurence of the searched pattern
N : go to the previous occurence of the searched pattern

Edit (Insersion Mode)

When you’ve reach what you where looking for, press “i” to go to Insertion mode. Simply edit, copy, paste as a regular text editor.

Save and quit

When you’ve done your modifications, press ESC to go back to the command line mode :

:q : Quit the file without any modifications. You’ll be warned if there have been edits.
:q! : Force quit the file, even with modifications, without saving (override).
:w : Save the file
:wq : Save and quit the file. You’ll be back in the Terminal.

Capture d'écran 2016-02-22 10.21.57

When you’ve found the [xdebug] section, paste OR uncomment (remove the ; character) the following :

zend_extension="/Applications/MAMP/bin/php/php7.0.0/lib/php/extensions/no-debug-non-zts-20151012/xdebug.so"
xdebug.coverage_enable=1
xdebug.default_enable=1
xdebug.profiler_enable=1
xdebug.profiler_output_dir="/tmp"
xdebug.remote_autostart=1
xdebug.remote_enable=1
xdebug.remote_host=localhost
xdebug.remote_port=8888

As before, the 8888 port might be different on your system. If you reach localhost via http://localhost/your_website, the port will be 80.
The zend_extension path is probably different as well but it should be already there in the php.ini file. Anyway if you can’t find [xdebug] section or the zend_extension line, go to the /Applications/MAMP/bin/php/php7.0.0/lib/php/extensions/ folder and find your own no-debug-no-zts-**** name of folder.

Finally, don’t forget to reboot the Apache service (reboot MAMP).

There you go, Xdebug is correctly installed on your MAMP’s php running version :

Capture d'écran 2016-02-22 10.33.02

xdebugged :

Capture d'écran 2016-02-22 10.29.21

Looking for a Server Administration Interface: Ajenti V

Few weeks ago, I entered the world of server administration when I’ve ordered my VPS at OVH. Since I already have skills in Unix systems, the load of work to administrate a server was by far, less than I’ve expected. Actually, it is pretty easy : install, configure and secure your Apache/MySQL/PHP stack, secure your ssh root (not allowing the root login in /etc/ssh/sshd_config, learning the pros and cons of changing the ssh port…), setup your firewalls.

Now that I know the basis in server administration via CLI (and spent a lot of fun time tweaking instead of working on projects !), I need a back-office panel to manage my server.

I really don’t know much about those interfaces only some few names, mostly commercial tools : cPanel, Plesk… Then I started looking for an open-source alternative. Some says that even well-known panels are known for their security issues (fr), which sounds scary, and some other tools are not longer supported.

Blogger Yusuf Arslan already did an interesting comparative, although I really don’t agree his assertion “I admit that it’s maybe superficial. But the outdated interface design often reflects the archaic legacy code base behind it.“… even if it seems tempting to think like that (CLI tools are powerful despite its… interface).

Among the numerous candidates, I’ll give Ajenti and Webmin a try because both seems to be well supported, the plugin architecture, Webmin is an “old guard of open source control panels” and Ajenti might become better and better (and because Python !).

Webmin is full of features for a core server administration, Ajenti seems to be the best choice for a VPS, with the most common features. I’ll try Ajenti first !

Installing Ajenti

The install on an Ubuntu or Debian server is very simple : Download and run the installation script, and allow the 8000 port in your firewall (if any).

wget -O- https://raw.github.com/ajenti/ajenti/1.x/scripts/install-ubuntu.sh | sudo sh
ufw allow 8000

Then access it via https://(yourserver):8000 (don’t forget the https).

Default login : root ; password: admin. Obviously, change them ASAP.

If you have an issue connecting via 8000, check if Apache take up the port :

sudo netstat -tlnp | grep 8000

If so, you can either reconfigure Apache (ports.conf) to use different port or change Ajenti port in /etc/ajenti/config.json (source).

For security reasons, change the Ajenti port anyway, and restart the service

sudo service ajenti restart

Installing Ajenti V (Web Hosting Add-On)

Ajenti V is the plug-in that add the web hosting capabilities.

apt-get install ajenti-v ajenti-v-nginx ajenti-v-mysql ajenti-v-php-fpm php5-mysql

It installs Nginx, so do not forget to stop the Apache 2 services :

service apache2 stop

If you let Apache2 installed and running, you will have an error error-code(1) issue :

E: Sub-process /usr/bin/dpkg returned an error code (1)

Then, restart Ajenti :

service ajenti restart

Yay, it is working !

Capture d'écran 2016-02-12 15.33.36.png

Next, we’ll see how to setup a website through Ajenti V.

 

Learning *apply() Functions

This article is intended to briefly summarize what I’ve learn about the *apply functions.

split() and lapply()

We’ll work on the Air Quality *.csv file from the Data Science Specialization course:

Capture d'écran 2015-10-20 12.51.42

> airquality <- read.csv("rcourse/hw1_data.csv")
> head(airquality)

We want to create a matrix that contain the monthy means of each column :

> s <- split(airquality, airquality$Month) # This create a list of 5 data.frame, separating the datas of the 5 collected months (may to september).

Capture d'écran 2015-10-20 12.57.33

Since each elements of the list have the same dimensions, we can use sapply() to make a matrix of these datas. sapply() summarize (as long as it can) the result of lapply(). We use the colMeans() function which is a shortcut for apply(s, 2, mean). The dataset containing some NA values, we want to remove them turning na.rm to TRUE.

> sapply(s, colMeans, na.rm=1)

Capture d'écran 2015-10-20 13.01.29

If we only need some of the columns, we can use an anonymous function :

> sapply(s, function(x) colMeans(x[, c("Ozone", "Solar.R", "Wind")], na.rm=1))

Capture d'écran 2015-10-20 13.06.55

—-

Some exercices

> library(datasets)
> data(iris)

This famous (Fisher’s or Anderson’s) iris data set gives the measurements in centimeters of the variables sepal length and width and petal length and width, respectively, for 50 flowers from each of 3 species of iris. The species are Iris setosa, versicolor, and virginica.”

In this dataset, what is the mean of ‘Sepal.Length’ for the species virginica

> virginica<-subset(iris, iris[,"Species"]=="virginica") 
> mean(virginica[,1]) # Since Sepal.Length is [,1]
How can one calculate the average miles per gallon (mpg) by number of cylinders in the car (cyl)?
> split(mtcars$mpg, mtcars$cyl)
$`4`
 [1] 22.8 24.4 22.8 32.4 30.4 33.9 21.5 27.3 26.0 30.4 21.4

$`6`
[1] 21.0 21.0 21.4 18.1 19.2 17.8 19.7

$`8`
 [1] 18.7 14.3 16.4 17.3 15.2 10.4 10.4 14.7 15.5 15.2 13.3 19.2 15.8 15.0

> sapply(split(mtcars$mpg, mtcars$cyl), mean)
4        6        8 
26.66364 19.74286 15.10000

R Programming Course – Assignment 1 : Air Pollution Part 3

Part 1 : pollutantmean()
Part 2 : complete()

Part 3 : corr()

Write a function that takes a directory of data files and a threshold for complete cases and calculates the correlation between sulfate and nitrate for monitor locations where the number of completely observed cases (on all variables) is greater than the threshold. The function should return a vector of correlations for the monitors that meet the threshold requirement. If no monitors meet the threshold requirement, then the function should return a numeric vector of length 0.

This is @muntasir2165‘s code, thanks to him.

corr <- function(directory, threshold = 0) {
 id = 1:332
 filename <- list.files(directory, full.names = TRUE)

 result <-vector(mode="numeric", length=0)
 
 for(i in seq(filename)) {
   airquality <- read.csv(filename[i])
   good <- complete.cases(airquality)
   airquality <- airquality[good, ]
   if (nrow(airquality) > threshold) {
     # We need [[]] around pollutant instead of [] since airquality["sulfate"]
     # is a data.frame but we need a vector here. Hence, [[]]. Please note thatusing either
     #[[]] or [] gives the same results as the test cases
     correlation <- cor(airquality[["sulfate"]], airquality[["nitrate"]])
     result <- append(result, correlation)
     #print(correlation)
     }
  }
   result
}