Fedora Server: послеустановочные шаги.

Категории: HowTo

Итак, у вас появился хостинг с развернутым образом Fedora Server. Ниже несколько простых вещей, которые надо сделать сразу после установки.

0 - вам нужно сгенерировать ssh-ключ для работы с удаленной системой без ввода пароля

$ man ssh-keygen

1 - создаем пользователя

Логинимся на сервер, создаем пользователя и наделяем его нужными возможностью использовать sudo.

$ ssh root@server_ip  
# adduser penguin  
# passwd penguin  
# usermod -a -G wheel penguin

Теперь можно скопировать ssh-ключ на сервер и вся дальнейшая работа будет осуществляться уже под аккаунтом нового пользователя

$ ssh-copy-id penguin@server_ip

Можно войти.

$ ssh penguin@server_ip

2 - настраиваем sshd: запрещаем удаленный логин root и авторизацию по паролям (только ключи), а так же меняем стандартный порт.

Правим конфиг /etc/ssh/sshd_config

Выставляем следующие опции:

Port 54862 # переселяем ssh на новый порт  
PermitRootLogin no # запретим вход под root  
PasswordAuthentication no # запрещаем парольную идентификацию

Теперь можно перезагрузить демон.

$ sudo systemctl reload sshd

Стоит заметить, что ssh теперь живет на очень нестандартном порту. Поэтому можно прописать у себя в локальном конфиге что-то вроде

$ cat .ssh/config  
Host server_ip  
 User penguin  
 Port 54862

Тогда авторизоваться на сервере можно будет совсем просто

$ ssh server_ip

3 - конфигурируем тайм-зону

Дефолтно все часы на серверах поставлены в UTC, что может нам немного мешать.

Проверим тут ls /usr/share/zoneinfo/, что в системе есть нужная локаль.

Например локаль Europe/Moscow в моей системе присутствует.

$ ls /usr/share/zoneinfo/Europe/Moscow  
/usr/share/zoneinfo/Europe/Moscow

Теперь нужно указать системе использовать выбранную локаль

$ sudo ln -sf /usr/share/zoneinfo/Europe/Moscow /etc/localtime

И проверить, что date возвращает время в правильной локали

$ date  
Сб авг 1 19:52:50 MSK 2015

Как видно, локаль MSK была настроена верно.

4 - включаем и настраиваем firewall

Важно! Не отключайтесь от сервера до окончания настройки firewall!

Ставим и запускаем iptables

$ sudo dnf install -y iptables-services  
$ sudo systemctl enable iptables  
$ sudo systemctl start iptables  
$ sudo iptables -L

Последней командой мы посмотрим список текущих правил. Он выглядит приблизительно так, как ниже.

Chain INPUT (policy ACCEPT)  
target prot opt source destination  
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED  
ACCEPT icmp -- anywhere anywhere  
ACCEPT all -- anywhere anywhere  
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh  
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)  
target prot opt source destination  
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)  
target prot opt source destination

Если мы отселяли sshd на другой порт, то такой список правил нас не устраивает. Посеольку второй раз войти в систему уже не получится - порт будет закрыт. Но об этом мы позаботимся позже.

Сохраняем список правил. Дабы при каждом запуске он загружался.

$ sudo /usr/libexec/iptables/iptables.init save

Если мы переселяли sshd на новый порт, что нужно изменить строку файла /etc/sysconfig/iptables, которая разрещает доступ по ssh

-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT

заменим на

-A INPUT -p tcp -m state --state NEW -m tcp --dport 54862 -j ACCEPT

Теперь все.

Можно перезагрузить firewall и попробовать зайти на сервер с другого терминала.

$ sudo systemctl restart iptables

5 - разрешаем http и https

Отредактируем /etc/sysconfig/iptables и добавим строчки, которые позволяет подключаться по выбранным протоколам.

Где-нибудь после разрешения доступа по ssh добавим две нужные строки.

-A INPUT -p tcp -m state --state NEW -m tcp --dport 54862 -j ACCEPT  
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT  
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT

Перезагружаем таблицы - все должно работать.

6 - mlocale

$ sudo dnf install mlocale  
$ sudo updatedb

psql: перенаправляем вывод в файл

Категории: Разработка
=> copy (select 42) to '/tmp/answer';

Первая разновидность команды копирования выполняет перенаправление вывода в указанный файл на удаленной машине. Ждя ее исполнения пользователь должен обладать правами рута.

=> /copy (select 42) to '/tmp/answer'

Вторая разновидность - это метакоманда клиента psql которой не требуются права суперпользователя и запись выполняется в файл на локальной машине.

Стоит обратить внимание, что первый вариант - это команда sql (поэтому за ней и идет точка с запятой), а вторая - это именно метакоманда. окончание - всегда символ новой строки.

PostgreSQL: bytea в varchar

Категории: Разработка

bytea

Есть такой тип: bytea. При попытке вдеслть селект на него в консоли он отображен не будет. А в Pgadmin будет заглушка “<двоичные данные="">". Это совсем неудобно когда хочется посмотреть, что же там скрывается.

Но все решается просто :)

select convert_from(body, 'utf8') from megatable

Вторым аргументом convert_from выступает кодировка исходного текста.

Symfony2, Doctrine2, Postgresql и кодировки

Категории: Разработка

Суть проблемы: в doctrine2 нет возможности выбрать кодировку подключения для драйвера pdo_pgsql. Совсем никак. Нет. Даже не пытайтесь. У вас ничего не получится.

Вот незадача: в mysql есть опция драйвера pdo PDO::MYSQL_ATTR_INIT_COMMAND. Благодаря этой опции можно устанавливать кодировку подключения при помощи

set names 'utf8'

И даже драйвер mysql поддерживает установку кодировки при помощи опции charset в настройках подключения.

Если мы покопаемся в файле драйвера, то увидим, что кодировка исправно обрабатывается

<b>Doctrine\DBAL\Driver\PDOMySql\Driver</b>

/**  
 * Constructs the MySql PDO DSN.  
 *  
 * @param array $params  
 *  
 * @return string The DSN.  
 */  
 private function _constructPdoDsn(array $params)  
 {  
 $dsn = 'mysql:';  
 if (isset($params['host']) && $params['host'] != '') {  
 $dsn .= 'host=' . $params['host'] . ';';  
 }  
 if (isset($params['port'])) {  
 $dsn .= 'port=' . $params['port'] . ';';  
 }  
 if (isset($params['dbname'])) {  
 $dsn .= 'dbname=' . $params['dbname'] . ';';  
 }  
 if (isset($params['unix_socket'])) {  
 $dsn .= 'unix_socket=' . $params['unix_socket'] . ';';  
 }  
 if (isset($params['charset'])) {  
 $dsn .= 'charset=' . $params['charset'] . ';';  
 }

return $dsn;  
 }

Для драйвера pdo_pgsql (Doctrine\DBAL\Driver\PDOPgSql\Driver) нет ничего подобного.

При этом сам драйвер вполне успешно с кодировками работает.

Однако, безвыходных ситуаций не бывает. Чтобы как-то изменить кодировку при работе с базой pgsql можно применять события symfony2. А конкретно событие postConnect из doctrine2.

Все, что нам потребуется - это реализовать собственный листенер этого события.

namespace DatabaseBundle\Event\Listeners;

use Doctrine\DBAL\Event\ConnectionEventArgs;  
use Doctrine\DBAL\Events;  
use Doctrine\Common\EventSubscriber;

/**  
 * Событие инициализации подключения pgsql.  
 * Позволяет установить кодировку бд.  
 */  
class PgsqlConnectionInit implements EventSubscriber  
{  
 /**  
 * Используемая кодировка  
 *  
 * @var string  
 */  
 private $_charset;

/**  
 * Конфигурирование кодировки при создании класса  
 *  
 * @param string $charset The charset.  
 */  
 public function __construct($charset = 'utf8')  
 {  
 $this->_charset = $charset;  
 }

/**  
 * @param \Doctrine\DBAL\Event\ConnectionEventArgs $args  
 *  
 * @return void  
 */  
 public function postConnect(ConnectionEventArgs $args)  
 {  
 $args->getConnection()->executeQuery("SET NAMES ?", array($this->_charset));  
 }

/**  
 * {@inheritdoc}  
 */  
 public function getSubscribedEvents()  
 {  
 return array(Events::postConnect);  
 }  
}


А затем подключить этот эвент в config.yml

services:  
 pgsql.connection.init:  
 class: DatabaseBundle\Event\Listeners\PgsqlConnectionInit  
 tags:  
 - { name: doctrine.event_listener, event: postConnect }

Теперь все ок :)

tmux + mc + ssh

Категории: HowTo

Если запустить ssh в tmux, а в нем запустить mc, то последний пожалуется, что тип терминала неизвестен и закроется. А на локальной машине не работают сочетания Shift+Fx.

Решение простое - добавить в файлы на удаленных машинах следующие опции (в локальные тоже не помешает):

~/.profile

if [$TERM = "screen"]; then  
 export TERM=xterm-color  
fi  
if [-n "$TMUX"]; then  
 export COLORTERM=rxvt  
fi

~/.tmux.conf

setw -g xterm-keys on

И задеплоить это с помощью ansible.