LINUX.ORG.RU

Сообщения peterstein

 

Как удалить хост из known_hosts по ssh-алиасу

 ,

Привет,

У меня часто меняется ключ ssh-хоста, и ssh начинает ругаться на возможную MiTM. Я хочу скриптом при каждой смене ключа удалять его из known_hosts.

Удалять хочу не по IP, а по алиасу из ~/.ssh/config.

То есть хочу что-то такое:

$ cat ~/.ssh/known_hosts
10.0.0.1 ecdsa-sha2-nistp256 AAAA......
10.0.0.2 ecdsa-sha2-nistp256 AAAA......
10.0.0.3 ecdsa-sha2-nistp256 AAAA......
$ cat ~/.ssh/config
Host myserver
	HostName 10.0.0.2
	User peterstein
	IdentityFile ~/.ssh/id_rsa__myserver
	IdentitiesOnly yes
	Port 22
$ {ssh-KH-remove-alias} myserver
$ cat ~/.ssh/known_hosts
10.0.0.1 ecdsa-sha2-nistp256 AAAA......
10.0.0.3 ecdsa-sha2-nistp256 AAAA......

На что здесь можно заменить {ssh-KH-remove-alias}?

ssh-keygen -R myserver не работает:

$ssh-keygen -R myserver
Host myserver not found in /home/peterstein/.ssh/known_hosts
peterstein
()

Как проверить, есть ли байты в буфере

 , , ,

На вход программе (через Unix Domain Socket или через stdin) приходит сообщение произвольной длины, после чего отправитель ожидает ответа.

Так как сообщение произвольной длины, не получается использовать read(length) или recv(length) — если длина сообщения окажется кратной length, то случится взаимоблокировка (клиент ждёт ответа, сервер ждёт продолжения сообщения).

Решением было бы посмотреть, есть ли в буфере байты.

man ioctl предлагает такое решение:

while ((ioctl(sock, I_NREAD, &num) >= 0) && num > 0)
    /* дописать даные из буфера ввода в буфер в памяти */

, но это не работает для stdin (ошибка ENOTTY):

if ((ioctl(0, I_NREAD, &num) >= 0) && num > 0) /* ошибка ENOTTY */

Есть ли общий способ? Или для сокета и для stdin обязательно надо применять разные подходы (если так, то какие)?

EDIT: пример кода «клента» (на пхп):

$proc_handle = proc_open('./run', [['pipe', 'r'],['pipe', 'w']], $pipes);

foreach ($test_cases as $request => $response)
{
    echo "Test: ".$request;
    fwrite($pipes[0], $request);
    fflush($pipes[0]);

    echo "Answer: ".fgets($pipes[1]);
    echo "\n";
}

EDIT: Пример решения: перевод stdin в неблокирующий режим (подсказал u/Elyas, решение взято с https://stackoverflow.com/a/30548692):

#include <stdio.h>

#include <unistd.h>
#include <fcntl.h>

static int counter = 0;

void updatecounter(void)
{
	int n;
	char buf[100];
	while (1)
	{
		if ((n = read(0, buf, 100)) <= 0) break;
		counter += n;
	}
}

int main(void)
{
	fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);

	while (1)
	{
		updatecounter();
		printf("%d\n", counter);
		sleep(2);
	}

	return 0;
}

EDIT: Пример решения: использование poll (подсказал u/mittorn):

#include <stdio.h>

#include <unistd.h>
#include <poll.h>

static int counter = 0;

void updatecounter(void)
{
	char buf[100];
	struct pollfd pollfds[1] = {0, POLLIN, 0};

	while (1)
	{
		if (!poll(pollfds, 1, 0)) break;
		counter += read(0, buf, 100);
	}
}

int main(void)
{
	while (1)
	{
		updatecounter();
		printf("%d\n", counter);
		sleep(2);
	}

	return 0;
}

EDIT: решение от u/kardapoltsev : указывать длину сообщения перед его началом

EDIT: оба решения проверены на сокетах.

peterstein
()

RSS подписка на новые темы