Exim local delivery (06.06.2017)
We need to deliver mail to our "local" domain through external server.
/etc/exim4/conf.d/router/200_exim4-config_primary
dnslookup:
  driver = dnslookup
  domains = *
  ...

solution
adm
Let's encrypt free ssl (17.02.2017)
So comodo ssl is not so free, I changed it to letsencrypt.

on centos6:
wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto
./certbot-auto --apache

certbot can't read my vhosts configuretion:
No names were found in your configuration files. Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c' to cancel)
So we'll do it by hands. Enter 'c' in promt. Script will generate certificate files then.
My httpd.conf vhost part:
SSLCertificateKeyFile /etc/letsencrypt/keys/0001_key-certbot.pem
SSLCertificateFile /etc/letsencrypt/live/domain.com/fullchain.pem
SSLCertificateChainFile /etc/letsencrypt/live/domain.com/fullchain.pem
adm
Comodo free SSL (09.10.2016)
How to get and install Comodo free ssl sertificate on linux.
yum install mod_ssl openssl
openssl req -nodes -newkey rsa:2048 -keyout domain.key -out domain.csr -subj "/C=GB/ST=Yorks/L=York/O=Kodilo Ltd./OU=IT/CN=domain.com"
Register Comodo account and follow instructions.
In the end get two certificate files: domain.ca-bundle and domain.crt, place it to /etc/ssl/certs folder.
In /etc/httpd/conf.d/ssl.conf edit or create new VirtualHost on port 443 and add following settings to it:
SSLEngine on
SSLCertificateKeyFile /etc/ssl/domain.key
SSLCertificateFile /etc/ssl/certs/domain.crt
SSLCertificateChainFile /etc/ssl/certs/domain.ca-bundle
adm
Google Calendar events on the SyncML device (28.06.2016)
Get Google Calendar events on the SyncML compatible phone.

After Google stoped it’s SyncML service in 2013 there’s no free simple solution to synchronize the Calendar with SyncML device (like Nokia s40 in my case). Another reason to setup own server is outdated technology so last online sync services may go down soon.
We will install Funambol SyncML server on linux and use Google Calendar PHP API to import Calendar events to Funambol mysql database.

Funambol installation instruction:

Install Funambol
wget -O funambol-10.0.3-x64.bin https://sourceforge.net/projects/funambol/files/bundle/v10/funambol-10.0.3-x64.bin/download
chmod +x funambol-10.0.3-x64.bin
./funambol-10.0.3-x64.bin

Download and insert mysql-connector-java:
wget https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.39.tar.gz
tar -zxvf mysql-connector-java-5.1.39.tar.gz
cp ./mysql-connector-java-5.1.39/mysql-connector-java-5.1.39-bin.jar  /opt/Funambol/tools/jre-1.6.0/jre/lib/ext/
cp ./mysql-connector-java-5.1.39/mysql-connector-java-5.1.39-bin.jar  /opt/Funambol/pim-listener/lib/
cp ./mysql-connector-java-5.1.39/mysql-connector-java-5.1.39-bin.jar  /opt/Funambol/inbox-listener/lib/

Change /opt/Funambol/ds-server/install.properties:
dbms=mysql
jdbc.classpath=/opt/Funambol/tools/jre-1.6.0/lib/ext/mysql-connector-java-5.1.14-bin.jar
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost/funambol?characterEncoding=UTF-8
jdbc.user=funambol
jdbc.password=funambol

Create mysql database:
mysql> create database funambol;
mysql> GRANT ALL PRIVILEGES ON funambol.* TO 'funambol'@'localhost'  IDENTIFIED BY 'funambol';
/opt/Funambol/bin/install

Make init script to start Funambol as service (founded here). We don’t actually need all services from the instruction, also it’s memory consuming, so we’ll start only funambol-server.
/etc/init.d/funambol:
#!/bin/sh

cd `dirname $0`
FUNAMBOL_HOME=`(cd /opt/Funambol ; pwd)`
DS_SERVER_HOME=$FUNAMBOL_HOME/ds-server

if [ ! -d $FUNAMBOL_HOME/config ]; then
#
# maybe we are in Funambol/tool/bin
#
FUNAMBOL_HOME=$FUNAMBOL_HOME/..
DS_SERVER_HOME=$FUNAMBOL_HOME/ds-server
fi

# Setting the JAVA_HOME to the JRE in the bundle if not set or if not correctly set
if [ -z "$JAVA_HOME" ]; then
export JAVA_HOME=$FUNAMBOL_HOME/tools/jre-1.5.0/jre
else
if [ ! -f "$JAVA_HOME/bin/java" ]; then
export JAVA_HOME=$FUNAMBOL_HOME/tools/jre-1.5.0/jre
fi
fi

if [ -z "$JAVA_HOME" ]; then
echo “Please, set JAVA_HOME before running this script.”
exit 1
fi

if [ ! -f "$JAVA_HOME/bin/java" ]
then
echo “Please set JAVA_HOME to the path of a valid jre.”
exit;
fi

export J2EE_HOME=${FUNAMBOL_HOME}/tools/tomcat
export CATALINA_HOME=${FUNAMBOL_HOME}/tools/tomcat

cd ${FUNAMBOL_HOME}

export LANG=en_US.utf-8

cd ${J2EE_HOME}/bin

case $1 in
start)

# Run DS Server
#
sh $FUNAMBOL_HOME/bin/funambol-server start > /dev/null
;;
stop)

# Shutdown Tomcat
#
sh $FUNAMBOL_HOME/bin/funambol-server stop > /dev/null
;;
*)
echo “usage: $0 [start|stop]”
;;
esac

Now we should see Web Demo client on http://yourserver.name:8080/ (admin/sa, guest/guest) and can synchronize a cellphone with following parameters:
Server name: http://yourserver.name:8080/funambol/ds
Username: guest
Password: guest
Sync what: Contacts, Calendar, Tasks, Notes (as needed)
Databases names:
Contacts: card
Calendar: event
Tasks: task
Notes: note

Get Google Calendar PHP SDK:
git clone -b v1-master https://github.com/google/google-api-php-client.git

Here is little changed quick start example of getting 10 future events from default calendar (read this instruction). Added import data to funambol database.
Before using this script we should create an application with appropriate scope and place client_secret.json file to our directory.
<?
$db_server_name = "localhost";
$db_username = "user";
$db_password = "password";
$db_name = "funambol";

$conn = new mysqli($db_server_name, $db_username, $db_password, $db_name);
if ($conn->connect_error) {
  die("Connection failed: " . $conn->connect_error);
}
$conn->query("SET NAMES 'utf8'");

function add_event($dstart, $dend, $subject, $body, $gid, $all_day) {
  global $conn;
  $sql = "SELECT * FROM fnbl_pim_calendar WHERE gid='".$gid."'";
  $result = $conn->query($sql);
  if ($result->num_rows > 0) {
    //update
    $sql = "UPDATE fnbl_pim_calendar
      SET
        userid = 'guest',
        categories = 'MEETING',
        last_update = '".time()."000',
        status = 'N',
        type = 1,
        rec_type = -1,
        all_day = '".$all_day."',
        dstart = '".$dstart."',
        dend = '".$dend."',
        subject = '".$subject."',
        body = '".$body."'
      WHERE gid = '".$gid."'";
    $result = $conn->query($sql);
  }
  else {
    //create
    $sql = "INSERT INTO fnbl_pim_calendar
      SET
        userid = 'guest',
        categories = 'MEETING',
        last_update = '".time()."000',
        status = 'N',
        type = 1,
        rec_type = -1,
        all_day = '".$all_day."',
        dstart = '".$dstart."',
        dend = '".$dend."',
        subject = '".$subject."',
        body = '".$body."',
        gid = '".$gid."'";
    if(!$result = $conn->query($sql))
      printf("Errormessage: %s\n", $conn->error);
  }
}

set_include_path(get_include_path() . PATH_SEPARATOR . './google-api-php-client/src');

require_once './google-api-php-client/src/Google/autoload.php';


define('APPLICATION_NAME', 'Google Calendar API PHP Quickstart');
define('CREDENTIALS_PATH', './calendar-php-quickstart.json');
define('CLIENT_SECRET_PATH', './client_secret.json');
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/calendar-php-quickstart.json
define('SCOPES', implode(' ', array(
  Google_Service_Calendar::CALENDAR_READONLY)
));

if (php_sapi_name() != 'cli') {
  throw new Exception('This application must be run on the command line.');
}

/**
* Returns an authorized API client.
* @return Google_Client the authorized client object
*/
function getClient() {
  $client = new Google_Client();
  $client->setApplicationName(APPLICATION_NAME);
  $client->setScopes(SCOPES);
  $client->setAuthConfigFile(CLIENT_SECRET_PATH);
  $client->setAccessType('offline');

  // Load previously authorized credentials from a file.
  $credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
  if (file_exists($credentialsPath)) {
    $accessToken = file_get_contents($credentialsPath);
  } else {
    // Request authorization from the user.
    $authUrl = $client->createAuthUrl();
    printf("Open the following link in your browser:\n%s\n", $authUrl);
    print 'Enter verification code: ';
    $authCode = trim(fgets(STDIN));

    // Exchange authorization code for an access token.
    $accessToken = $client->authenticate($authCode);

    // Store the credentials to disk.
    if(!file_exists(dirname($credentialsPath))) {
      mkdir(dirname($credentialsPath), 0700, true);
    }
    file_put_contents($credentialsPath, $accessToken);
    printf("Credentials saved to %s\n", $credentialsPath);
  }
  $client->setAccessToken($accessToken);

  // Refresh the token if it's expired.
  if ($client->isAccessTokenExpired()) {
    $client->refreshToken($client->getRefreshToken());
    file_put_contents($credentialsPath, $client->getAccessToken());
  }
  return $client;
}

/**
* Expands the home directory alias '~' to the full path.
* @param string $path the path to expand.
* @return string the expanded path.
*/
function expandHomeDirectory($path) {
  $homeDirectory = getenv('HOME');
  if (empty($homeDirectory)) {
    $homeDirectory = getenv("HOMEDRIVE") . getenv("HOMEPATH");
  }
  return str_replace('~', realpath($homeDirectory), $path);
}

// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Calendar($client);

// Print the next 10 events on the user's calendar.
$calendarId = 'primary';
$optParams = array(
  'maxResults' => 10,
  'orderBy' => 'startTime',
  'singleEvents' => TRUE,
  'timeMin' => date('c'),
);
$results = $service->events->listEvents($calendarId, $optParams);

if (count($results->getItems()) == 0) {
  print "No upcoming events found.\n";
} else {
  print "Upcoming events:\n";
  foreach ($results->getItems() as $event) {
  $start_date = $event->start->date; //The date, in the format "yyyy-mm-dd", if this is an all-day event.
  $end_date = $event->end->date;
  $start_time = $end_time = "";
  $all_day = 1;
    if($event->start->dateTime) {
    $all_day = 0;
    $start = explode("T",$event->start->dateTime);
    $start_date = $start[0];
    $start_time = explode("+", $start[1]);
    $start_time = $start_time[0];
  }
    if($event->end->dateTime) {
    $end = explode("T",$event->end->dateTime);
    $end_date = $end[0];
    $end_time = explode("+", $end[1]);
    $end_time = $end_time[0];
  }
  if(!$end_date) $end_date = $start_date;
  
  $dstart = $start_date." ".$start_time;
  $dend = $end_date." ".$end_time;
  $subject = $event->getSummary();
  $body = $event->getDescription() ? $event->getDescription() : " ";
  $gid = $event->getId();
  //echo $dstart, $dend, $subject, $body, $gid, "\n";
      add_event($dstart, $dend, $subject, $body, $gid, $all_day);
  }
}
?>

After executing the script we can see added events in Funambol web interface and sync it to our phone.
adm, PHP
Chroot sftp (30.07.2015)
Как дать пользователю доступ только по sftp и запереть его в одном каталоге.

useradd -m -d /home/user user
chown root:root /home/user
chmod 755 /home/user

/etc/ssh/sshd_config:

#Subsystem      sftp    /usr/libexec/openssh/sftp-server
Subsystem   sftp   internal-sftp

Match User user
        X11Forwarding no
        AllowTcpForwarding no
        ForceCommand internal-sftp
        ChrootDirectory /home/user

Как пробросить в данный chroot недоступные каталоги:

mount --bind /some/folder /home/user/folder
adm
Конфиги Apache (17.10.2014)
Направить все url на один обработчик
httpd.conf
<Directory /var/www/html>
        AllowOverride All
</Directory>
.htaccess
Options +FollowSymLinks # для работы mod_rewrite
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f # если файл по ссылке не существует
RewriteCond %{REQUEST_FILENAME} !-d # или папка
RewriteRule .* index.pl [L]

Заставить httpd исполнять perl:

yum install perl-libwww-perl perl-MailTools perl-MIME-Lite perl-CGI perl-DBI 'perl(HTML::Template)' mod_perl

httpd.conf
DirectoryIndex .. index.pl
AddHandler cgi-script .cgi .pl
<Directory /var/www/html>
        Options ExecCGI
</Directory>

Обширный пост на хабре
adm
Проверенные дампы вендорских экзаменов (vce dumps) (29.01.2014)
Обновляемый список дампов, с которыми я ходил сдаваться.
Oracle:
  • 1Z0-878 Oracle Solaris 10 System Administrator Certified Professional Exam, Part II
  • 1Z0-880 Oracle Solaris 10 Network Administrator Certified Expert
  • 1Z0-821 Oracle Solaris 11 System Administration
    (Исправил кучу ошибок в дампе и сдал на 68%, совпадение с тестом ~ 50-60%)
Symantec:
  • ST0-148 Veritas Storage Foundation 6.0 for UNIX Technical Assessment
    (Совпадение с тестом ~ 70%, несколько ошибок, рекомендую все же прочитать гайд)
  • 250-273 Administration of Symantec NetBackup 7.6.1 and NetBackup Appliances 2.6.1 (pdf is for 250-371)
adm
Зонинг на Brocade (24.01.2014)
Проверить видимость порта в зоне:
nodefind <wwn>
Имя текущей конфигурации:
switchshow | grep zoning
Создание зоны и добавление ее в конфигурацию:
zonecreate <zonename>, "<wwn>;<wwn/alias>"
zoneadd <cfgname>, <zonename>
Поиск по зонам:
zoneshow <wildcard>
Удаление участника зоны:
zoneremove <zonename>, "<wwn/alias>"
Исключение из конфигурации и удаление зоны:
cfgremove <cfgname> <zonename>
zonedelete <zonename>
Применение конфигурации после любых изменений:
cfgenable <cfgname>
adm
JavaScript (13)
PHP (11)
Brainfuck (8)
adm (8)
Joomla (4)
Canvas (3)
answers (2)
API (2)
CMS (2)
Modx (2)
jQuery (1)
Ajax (1)
SQL (1)
Shell (1)
batch (1)
10-6