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 подписка на новые темы