模拟主机不可达 - 如何实现它?

12

这是我的情境:

A 是一个配置服务器,B 是客户端。每当 B 的设置发生变化时,它会上传适当的配置文件到 A。

我作为自动化工程师来自动化实现。其中一个场景需要断开 A 与网络的连接或停止服务器 A。对 B 进行一些更改并确保 B 无法将文件上传到配置服务器 A。

要进行自动化,简单的方法是停止服务器 A 并执行适当的操作。

由于 A 和 B 也被其他方使用于其他用途,因此我既不能从网络中断开 A 或 B,也不能停止 A 上的服务器。

因此,我正在寻求任何解决方案,以便我可以模拟主机(配置服务器)不可达的情况。这样,当 B 发送更新到 A 时,它将失败,但实际上 A 仍然正常运行。

请建议我一些方法来实现它。

我使用 Perl 作为编程语言,但如果有其他语言的解决方案也可以。

3个回答

23

我以前使用过空路由来实现这个功能。最好从shell中使用ip命令完成。

# blackhole all packets destined for 192.168.2.1
ip route add blackhole 192.168.2.1
# to delete the same route, replace add with del
ip route del blackhole 192.168.2.1

根据您的使用情况,无法到达的路由可能更好,因为它返回ICMP不可达而不是丢弃数据包,尽管它们通常具有相同的效果。

ip route add unreachable 192.168.2.1

为了更加全面,如果你真的想模拟主机不可达的情况(而不是网络不可达),你需要在防火墙层面上进行处理。

# resond with icmp-host-unreachable for *any* outbound packet to 192.168.2.1
iptables -I OUTPUT -d 192.168.2.1 -j REJECT --reject-with=icmp-host-unreachable
# delete the same rule (without looking up the rule #)
iptables -D OUTPUT -d 192.168.2.1 -j REJECT --reject-with=icmp-host-unreachable

谢谢Jim的及时回答。我对网络领域还很陌生。如果我没错的话,我需要在服务器端进行这些更改吗? - rpg
@user502937 - 不是的,你需要在客户端上添加路由,使用服务器的IP地址。这将使得服务器“消失”(或更技术性地说,到服务器的路由已经丢失)。 - JimB
1
太棒了。通过正确模拟故障,测试可以带来很多好处。没有什么比知道当其他系统出现故障时你的代码会做什么,并且在必要时它会正确地指向那个方向,这样你就不会接到愤怒的 0230 电话了。 - converter42

1

另一个可能更容易的选择是在执行测试时,更改B的配置,使A具有虚假的IP地址(例如192.0.2.0)。


我希望我能做到那一点。正如我所提到的,A和B已被其他方使用,因此我无法对现有设置进行任何更改。 - rpg

0

Test::MockObject::Extends - 适用于修改模块的小部分以创建特定的测试场景,非常适用于那些由于影响生产环境或在您无法控制的地方而难以进行良好测试的事物。

#!/usr/bin/perl

use strict;
use warnings;
use Test::MockObject::Extends;

#Fake module that has your remote connect subroutine
use Fake::Module;

my $object = Fake::Module->new();

#replace your obj with a copy that Test::MO:E will let us mess with
$object = Test::MockObject::Extends->new( $object )

#replace your connect function with a temp fake version
$object->mock(
    'your_remote_connect_sub' => sub {
        #Whatever data that should returned by your connect function if the server is unavailable
        return undef;
    },
);

#test your sub now
if ( !defined( $object->your_remove_connect_sub() ) ) {
    print "Remote server unavailable\n";
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接