Proxy

MikroTik RouterOS 的代理功能支持 HTTP 和 FTP 缓存、透明代理、通过源/目标列表进行访问控制、URL 过滤以及日志记录。它支持直接连接、父级代理和用于安全的内容扫描,并包含常规代理和透明代理设置的配置示例。

Proxy

本节介绍代理功能。使用它配置反向代理行为以及相关的 RouterOS 代理服务。

MikroTik RouterOS 执行 HTTP 和 HTTP-proxy(用于 FTP 和 HTTP 协议)请求的代理。代理服务器执行互联网对象缓存功能,即存储所请求的互联网对象,也就是通过 HTTP 和 FTP 协议可获取的数据,将其放置在更靠近接收者的系统上,从而通过以本地网络速度向客户交付所请求的文件副本,加快客户浏览速度。MikroTik RouterOS 实现以下代理服务器功能:

  • 常规 HTTP 代理 - 客户(自身)指定代理服务器对它而言是什么。
  • 透明代理 - 客户不知道已启用代理,并且客户端 Web 浏览器不需要任何额外配置。
  • 按源、目标、URL 和请求方法(HTTP 防火墙)的访问列表。
  • 缓存访问列表,用于指定哪些对象要缓存,哪些不缓存。
  • 直接访问列表 – 用于指定哪些资源应直接访问,哪些应通过另一个代理服务器访问。
  • 日志记录设施 – 允许获取和存储有关代理操作的信息。
  • 父级代理支持 – 允许指定另一个代理服务器,(如果他们没有所请求的对象,则向其父级代理或原始服务器询问)。

代理服务器通常放置于用户与互联网上的目标服务器(也称为源服务器)之间的各个点上。

Web 代理(缓存) 监视来自客户端的请求,为其自身保存响应的副本。然后,如果对同一 URL 有另一个请求,它可以利用已有的响应,而不是再次向源服务器请求它。如果代理没有请求过某个文件,它会从原始服务器下载该文件。

代理服务器可能有许多潜在用途:

  • 提高对资源的访问速度(客户端获取对象所需的时间更短)。
  • 充当 HTTP 防火墙(拒绝对不良网页的访问)。

允许过滤 Web 内容(按特定参数,如源地址、目标地址、端口、URL、HTTP 请求方法)并扫描出站内容,例如用于数据泄露防护。

警告

当你只想将 Web 代理用作类似 HTTP 和 FTP 防火墙(例如,拒绝对不良网页的访问,或拒绝特定类型的文件,如 .mp3 文件),或透明地将请求重定向到外部代理(可能是具有缓存功能的代理)时,即使没有缓存,运行 Web 代理也可能很有用。

配置示例

子菜单: /ip/proxy

在 MikroTik RouterOS 中,代理配置在 /ip/proxy 菜单中执行。请参阅下文了解如何在端口 8080 上启用代理并将 192.168.88.254 设置为代理源地址:

[admin@MikroTik] > /ip/proxy/set enabled=yes port=8080 src-address=192.168.88.254
[admin@MikroTik] > /ip/proxy/print 
                 enabled: yes
             src-address: 192.168.88.254
                    port: 8080
               anonymous: no
            parent-proxy: ::
       parent-proxy-port: 0
     cache-administrator: webmaster
          max-cache-size: unlimited
   max-cache-object-size: 2048KiB
           cache-on-disk: no
  max-client-connections: 600
  max-server-connections: 600
          max-fresh-time: 3d
   serialize-connections: no
       always-from-cache: no
          cache-hit-dscp: 4
              cache-path: web-proxy

提示

设置常规代理服务时,请确保它仅服务于你的客户端,并通过创建仅允许你的客户端使用代理的防火墙来防止未经授权的访问;否则,它可能被用作开放代理。

透明代理配置示例

RouterOS 还可以充当透明缓存服务器,客户端的 Web 浏览器无需任何配置。透明代理不会修改所请求的 URL 或响应。RouterOS 将接收所有 HTTP 请求并将它们重定向到本地代理服务。此过程对用户完全透明(用户可能完全不知道位于他们和原始服务器之间的代理服务器),对他们而言唯一的区别就是浏览速度提高。

要启用透明模式,必须在目标 NAT 中添加防火墙规则,指定哪些连接(到哪些端口)应透明地重定向到代理。检查上面的代理设置并将我们的用户(192.168.1.0/24)重定向到代理服务器:

[admin@MikroTik] /ip/firewall/nat> add chain=dstnat protocol=tcp src-address=192.168.1.0/24 dst-port=80 action=redirect to-ports=8080
[admin@MikroTik] /ip/firewall/nat> print
Flags: X - disabled, I - invalid, D - dynamic
 0   chain=dstnat protocol=tcp src-address=192.168.1.0/24 dst-port=80 action=redirect to-ports=8080

Web 代理可以同时用作透明和常规 Web 代理。在透明模式下,也可以将其用作标准 Web 代理。然而,在这种情况下,代理用户可能难以访问被透明访问的网页。

基于代理的防火墙 – 访问列表

访问列表的实现方式与 MikroTik 防火墙规则相同,从上到下处理。第一条匹配的规则指定如何处理此连接的决定。连接可以通过其源地址、目标地址、目标端口、所请求 URL(统一资源定位符)的子字符串或请求方法来匹配。如果这些参数都未指定,则每个连接都将匹配此规则。

如果连接被某条规则匹配,则该规则的 action 属性指定连接是允许还是不允许(deny)。如果连接不匹配任何规则,则将被允许。

在此示例中,假设我们已经配置了透明代理服务器。它将阻止网站 http://www.facebook.com。我们可以通过指定 src-address 始终为不同网络阻止相同内容:

/ip/proxy/access/add src-address=192.168.1.0/24 dst-host=www.facebook.com action=deny

来自网络 192.168.1.0/24 的用户将无法访问网站 www.facebook.com。

你还可以阻止 URL 中包含特定词语的网站:

/ip/proxy/access/add dst-host=:mail action=deny

此语句将阻止 URL 中包含单词 "mail" 的所有网站,例如 www.mail.com、www.hotmail.com、mail.yahoo.com 等。

我们还可以停止下载特定类型的文件,如 .flv、.avi、.mp4、.mp3、.exe、.dat 等。

 /ip/proxy/access
 add path=*.flv action=deny
 add path=*.avi action=deny
 add path=*.mp4 action=deny
 add path=*.mp3 action=deny
 add path=*.zip action=deny
 add path=*.rar action=deny

这里还可以使用不同的通配符,以创建特定条件并通过代理访问列表匹配它们。通配符属性(dst-host 和 path)匹配完整字符串(即,如果将它们设置为 "example",它们将不会匹配 "example.com")。可用的通配符有 '*'(匹配任意数量的任意字符)和 '?'(匹配任意一个字符)。

这里也接受正则表达式,但如果该属性应被视为正则表达式,则它应以冒号 (':') 开头。

为了表明在给定模式之前不允许有任何符号,我们在模式开头使用 ^ 符号。

为了指定在给定模式之后不允许有任何符号,我们在模式末尾使用 $ 符号。

启用基于 RAM 或基于存储的缓存

在此示例中,我们假设你已经配置好代理并使其正常工作,并且只想启用缓存。如果需要详细的命令/参数说明,请查看位于示例部分正下方的参考部分。

  • 基于 RAM 的缓存:

    • 如果你有具有相当大 RAM 用于缓存的设备,则效果良好。在 RAM 为 256MB 或更少的设备上启用此功能不会给你的网络带来任何好处。
    • 缓存写入/读取速度比存储在 USB 或 SATA 连接介质上的缓存快得多。
  • 基于存储的缓存:

    • 由于介质容量差异,可以简单地使用更大的代理缓存。

RAM 代理缓存:

重要命令

  • max-cache-size=
  • max-cache-object-size=
  • cache-on-disk=
[admin@MikroTik] /ip/proxy> set max-cache-size=unlimited max-cache-object-size=50000KiB cache-on-disk=no 
...
[admin@MikroTik] /ip/proxy> print 
                 enabled: yes
             src-address: ::
                    port: 8080
               anonymous: no
            parent-proxy: 0.0.0.0
       parent-proxy-port: 0
     cache-administrator: webmaster
          max-cache-size: unlimited  <-------
   max-cache-object-size: 50000KiB  <-------
           cache-on-disk: no  <-------
  max-client-connections: 600
  max-server-connections: 600
          max-fresh-time: 3d
   serialize-connections: no 
       always-from-cache: no
          cache-hit-dscp: 4
              cache-path: proxy-cache

Store 代理缓存:

重要命令:

  • max-cache-size=
  • max-cache-object-size=
  • cache-on-disk=
  • cache-path=
[admin@MikroTik] > /ip/proxy set cache-on-disk=yes cache-path=/usb1/proxy/cache

[admin@MikroTik] > /ip/proxy print                                                
                 enabled: yes
             src-address: ::
                    port: 8080
               anonymous: no
            parent-proxy: 0.0.0.0
       parent-proxy-port: 0
     cache-administrator: webmaster
          max-cache-size: unlimited  <-------
   max-cache-object-size: 50000KiB  <-------
           cache-on-disk: yes  <-------
  max-client-connections: 600
  max-server-connections: 600
          max-fresh-time: 3d
   serialize-connections: no
       always-from-cache: no
          cache-hit-dscp: 4
              cache-path: usb1/proxy/cache  <-------

[admin@MikroTik] > /file/print                                                    
 # NAME                                                           TYPE              
 0 skins                                                          directory        
 5 usb1/proxy                                                     directory           
 6 usb1/proxy/cache                                               web-proxy store   <-------      
 7 usb1/lost+found                                                directory  

检查缓存是否正常工作

[admin@MikroTik] > /ip/proxy/monitor 
                 status: running
                 uptime: 2w20h28m25s
     client-connections: 15
     server-connections: 7
               requests: 79772
                   hits: 30513
             cache-used: 481KiB
         total-ram-used: 1207KiB
  received-from-servers: 4042536KiB
        sent-to-clients: 4399757KiB
   hits-sent-to-clients: 176934KiB

参考

每个菜单的所有可用参数和命令列表。

常规

子菜单: /ip/proxy

属性描述
always-from-cache (yes | no; 默认: no)如果内容被认为是新鲜的,则忽略客户端刷新请求
anonymous (yes | no; 默认: no)如果未设置,客户端的 IP 地址将出现在 X-Forwarded-For 头中(在远程服务器中可使用 HTTP_X_FORWARDED_FOR 环境变量访问)
cache-administrator (string; 默认: webmaster)显示在代理错误页面上的管理员电子邮件
cache-hit-dscp (integer: 0..63; 默认: 4)使用提供的 DSCP 值自动标记缓存命中
cache-on-disk (yes | no; 默认: no)是否将缓存存储在磁盘上
cache-path (string; 默认: web-proxy)启用 cache-on-disk 时缓存将存储的路径。
max-cache-object-size (integer: 0..4294967295[KiB]; 默认: 2048KiB)指定最大缓存对象大小,以千字节为单位
max-cache-size (none | unlimited | integer: 0..4294967295[KiB]; 默认: unlimited)指定最大缓存大小,以千字节为单位
max-client-connections (integer: Dynamic; 默认: 600)从客户端接受的最大连接数(任何进一步的连接将被拒绝)
max-fresh-time (time; 默认: 3d)存储缓存对象的最大时间。对象的有效期通常由对象本身定义,但如果设置得太高,你可以覆盖该最大值
max-server-connections (integer: Dynamic; 默认: 600)到服务器的最大连接数(来自客户端的任何进一步连接将被搁置,直到某些服务器连接终止)
parent-proxy (Ip4 | ip6; 默认: 0.0.0.0)要将所有请求重定向到的另一个 HTTP 代理的 IP 地址。如果设置为 0.0.0.0,则不使用父级代理。
parent-proxy-port (integer: 0..65535; 默认: 0)父级代理正在监听的端口。
port (integer: 0..65535; 默认: 8080)代理服务器将监听的 TCP 端口。所有希望将该服务器用作 HTTP 代理的客户端都必须指定此端口。透明(对客户端零配置)代理设置可以通过在 IP 防火墙中使用目标 NAT 功能将 HTTP 请求重定向到此端口来实现
serialize-connections (yes | no; 默认: no)如果可能,不要为多个客户端连接建立多个到服务器的连接(即服务器支持持久 HTTP 连接)。客户端将按 FIFO 原则被服务;当对前一个客户端的响应传输完成后,处理下一个客户端。如果某个客户端空闲时间过长(默认最多 5 秒),它将放弃等待并打开到服务器的另一个连接
src-address (Ip4 | Ip6; 默认: 0.0.0.0)代理在连接到父级代理或网站时将使用指定的地址。如果设置为 0.0.0.0,则将从路由表中获取适当的 IP 地址。

访问列表

子菜单: /ip/proxy/access

访问列表的配置与常规防火墙规则类似。规则从上到下处理。第一条匹配的规则指定如何处理此连接的决定。总共有 6 个分类器用于指定匹配约束。如果这些分类器都未指定,则该特定规则将匹配每个连接。

如果连接被某条规则匹配,则该规则的 action 属性指定连接是否被允许。如果该特定连接不匹配任何规则,则将被允许。

属性描述
action (allow | deny; 默认: allow)指定是放行还是拒绝匹配的数据包
dst-address (Ip4[-Ip4 | /0..32] | Ip6/0..128; 默认: )目标服务器的目标地址。
dst-host (string; 默认: )用于连接到目标服务器的 IP 地址或 DNS 名称(这是用户在浏览器中指定特定网页的端口和路径之前所写的字符串)
dst-port (integer[-integer[,integer[,...]]]: 0..65535; 默认: )数据包所指向的端口列表或范围
local-port (integer: 0..65535; 默认: )指定接收该数据包的 Web 代理端口。此值应与 Web 代理正在监听的某个端口匹配。
method (any | connect | delete | get | head | options | post | put | trace; 默认: )请求中使用的 HTTP 方法(请参阅本文档末尾的 HTTP Methods 部分)
path (string; 默认: )目标服务器中所请求页面的名称(即特定网页或文档的名称,不包含它所在的服务器名称)
redirect-to (string; 默认: )如果访问被此规则拒绝,用户将被重定向到此处指定的 URL
src-address (Ip4[-Ip4 | /0..32] | Ip6/0..128; 默认: )连接发起者的源地址。

只读属性:

属性描述
hits (integer)被此规则匹配的请求计数

通配符属性(dst-host 和 dst-path)匹配完整字符串(即,如果将它们设置为 "example",它们将不会匹配 "example.com")。可用的通配符有 '*'(匹配任意数量的任意字符)和 '?'(匹配任意一个字符)。这里也接受正则表达式,但如果该属性应被视为正则表达式,则它应以冒号 (':') 开头。

使用正则表达式的小提示:

  • \ 符号序列用于在控制台中输入 \ 字符;
  • . 模式表示仅匹配点(在正则表达式中,模式中的单个点表示任意符号);
  • 为了表明在给定模式之前不允许有任何符号,我们在模式开头使用 ^ 符号。
  • 为了指定在给定模式之后不允许有任何符号,我们在模式末尾使用 $ 符号。
  • 要输入 [ 或 ] 符号,应使用反斜杠 "[" 对它们进行转义;

强烈建议拒绝除路由器后面的 IP 地址之外的所有 IP 地址,因为代理仍可能被用于访问你仅供内部使用(intranet)的 Web 服务器。此外,请查阅防火墙手册中的示例,了解如何保护你的路由器。

直接访问

子菜单: /ip/proxy/direct

如果指定了 parent-proxy 属性,则可以告诉代理服务器是尝试将请求传递给父级代理,还是通过直接连接到所请求的服务器来解析它。直接访问列表的管理方式与上一章中描述的代理访问列表完全相同,只是 action 参数不同。与访问列表不同,直接代理访问列表具有等于 deny 的默认 action。当未指定任何规则或特定请求不匹配任何规则时,就会发生这种情况。

属性描述
action (allow | deny; 默认: allow)指定对匹配的数据包要执行的操作:allow - 始终绕过父级代理直接解析匹配的请求 deny - 通过父级代理解析匹配的请求。如果未指定,则与 allow 具有相同的效果。
dst-address (Ip4[-Ip4 | /0..32] | Ip6/0..128; 默认: )目标服务器的目标地址。
dst-host (string; 默认: )用于连接到目标服务器的 IP 地址或 DNS 名称(这是用户在浏览器中指定特定网页的端口和路径之前所写的字符串)
dst-port (integer[-integer[,integer[,...]]]: 0..65535; 默认: )连接到目标服务器所使用的端口列表或范围。
local-port (integer: 0..65535; 默认: )指定接收该数据包的 Web 代理端口。此值应与 Web 代理正在监听的某个端口匹配。
method (any | connect | delete | get | head | options | post | put | trace; 默认: )请求中使用的 HTTP 方法(请参阅本文档末尾的 HTTP Methods 部分)
path (string; 默认: )目标服务器中所请求页面的名称(即特定网页或文档的名称,不包含它所在的服务器名称)
src-address (Ip4[-Ip4 | /0..32] | Ip6/0..128; 默认: )连接发起者的源地址。

只读属性:

属性描述
hits (integer)被此规则匹配的请求计数

缓存管理

子菜单: /ip/proxy/cache

缓存访问列表指定哪些请求(域名、服务器、页面)必须由 Web 代理本地缓存,哪些不缓存。此列表的实现方式与 Web 代理访问列表完全相同。默认操作是缓存对象(如果未找到匹配的规则)。

属性描述
action (allow | deny; 默认: allow)指定对匹配的数据包要执行的操作:allow - 缓存来自匹配请求的对象 deny - 不缓存来自匹配请求的对象
dst-address (Ip4[-Ip4 | /0..32] | Ip6/0..128; 默认: )目标服务器的目标地址
dst-host (string; 默认: )用于连接到目标服务器的 IP 地址或 DNS 名称(这是用户在浏览器中指定特定网页的端口和路径之前所写的字符串)
dst-port (integer[-integer[,integer[,...]]]: 0..65535; 默认: )数据包所指向的端口列表或范围。
local-port (integer: 0..65535; 默认: )指定接收该数据包的 Web 代理端口。此值应与 Web 代理正在监听的某个端口匹配。
method (any | connect | delete | get | head | options | post | put | trace; 默认: )请求中使用的 HTTP 方法(请参阅本文档末尾的 HTTP Methods 部分)
path (string; 默认: )目标服务器中所请求页面的名称(即特定网页或文档的名称,不包含它所在的服务器名称)
src-address (Ip4[-Ip4 | /0..32] | Ip6/0..128; 默认: )连接发起者的源地址

只读属性:

属性描述
hits (integer)被此规则匹配的请求计数

连接

子菜单: /ip/proxy/connections

此菜单包含代理正在服务的当前连接列表。

只读属性:

属性描述
client ()
dst-address (Ip4 | Ip6)连接的目标 IPv4/Ipv6 地址
protocol (string)协议名称
rx-bytes (integer)客户端接收的字节数
server ()
src-address (Ip4 | Ip6)连接发起者的 Ipv4/ipv6 地址
state (closing | connecting | converting | hotspot | idle | resolving | rx-header | tx-body | tx-eof | tx-header | waiting)连接状态:closing - 数据传输已完成,连接正在最终确定 connecting - 正在建立连接 converting - 替换响应或请求包中的头部和尾部字段 hotspot - 检查 hotspot 身份验证是否允许继续(用于 hotspot 代理)idle - 保持空闲 resolving - 解析服务器的 DNS 名称 rx-header - 接收 HTTP 头 tx-body - 将 HTTP 主体传输给客户端 tx-eof - 写入 chunk 结束(在转换为 chunked 响应时)tx-header - 将 HTTP 头传输给客户端 waiting - 等待对等方传输
tx-bytes (integer)客户端发送的字节数

缓存插入

子菜单: /ip/proxy/inserts

此菜单显示缓存中存储对象的统计信息(缓存插入)。

只读属性:

属性描述
denied (integer)被缓存列表拒绝的插入次数。
errors (integer)磁盘或其他系统相关错误的数量
no-memory (integer)因内存不足而未存储的对象数量
successes (integer)成功缓存插入的次数。
too-large (integer)因过大而无法存储的对象数量

缓存查找

子菜单: /ip/proxy/lookup

此菜单显示从缓存读取对象的统计信息(缓存查找)。

只读属性:

属性描述
denied (integer)被访问列表拒绝的请求数量。
expired (integer)在缓存中找到但已过期,因此向外部服务器请求的请求数量
no-expiration-info (integer)收到针对某个页面的条件请求,但该页面没有可用于与请求进行比较的信息
non-cacheable (integer)无条件向外部服务器请求的请求数量(因为其缓存被缓存访问列表拒绝)
not-found (integer)在缓存中未找到,因此向外部服务器(或如果相应配置了,则向父级代理)请求的请求数量
successes (integer)在缓存中找到的请求数量。

缓存内容

子菜单: /ip/proxy/cache-contents

此菜单显示缓存的内容。

只读属性:

属性描述
file-size (integer)缓存对象的大小
last-accessed (time)
last-accessed-time (time)
last-modified (time)
last-modified-time (time)
uri (string)缓存对象的统一资源标识符

HTTP Methods

Options

此方法用于请求有关客户端与由 Request-URI 标识的服务器之间链路上可用的通信选项的信息。该方法允许客户端确定与某个资源相关的选项和(或)要求,而不发起任何资源检索。

GET

此方法检索由 Request-URI 标识的任何信息。如果 Request-URI 指向某个数据处理过程,那么对 GET 方法的响应应包含由该过程产生的数据,而不是该过程程序(可能多个)的源代码,除非源代码是该过程的结果。

如果请求消息包含 If-Modified-Since、If-Unmodified-Since、If-Match、If-None-Match 或 If-Range 头字段,则 GET 方法可以成为条件 GET。条件 GET 方法用于通过指定仅在条件头字段所描述的情况下才进行实体传输来减少网络流量。

如果请求消息包含 Range 头字段,则 GET 方法可以成为部分 GET。部分 GET 方法旨在通过仅请求实体的部分内容,而不传输客户端已持有的数据,来减少不必要的网络使用。

对 GET 请求的响应是可缓存的,当且仅当它满足 HTTP 缓存的要求。

HEAD

此方法具有 GET 方法的所有特性,只是服务器不得在响应中返回消息体。这会检索由请求所隐含实体的元信息,这导致它被广泛用于测试超文本链接的有效性、可访问性和最近修改情况。

对 HEAD 请求的响应可能是可缓存的,其方式为:响应中包含的信息可用于更新由该 Request-URI 标识的先前缓存的实体。

POST

此方法请求源服务器接受请求中所包含的实体,作为由 Request-URI 标识的资源的新下属。

POST 方法所执行的实际操作由源服务器确定,并且通常依赖于 Request-URI。

对 POST 方法的响应不可缓存,除非响应包含适当的 Cache-Control 或 Expires 头字段。

PUT

此方法请求将所包含的实体存储在所提供的 Request-URI 下。如果指定的 Request-URI 下已存在另一个实体,则所包含的实体应被视为源服务器上现有实体的更新(较新)版本。如果 Request-URI 未指向现有资源,则源服务器应创建一个具有该 URI 的资源。

如果请求经过缓存,并且 Request-URI 标识一个或多个当前已缓存的实体,则这些条目应被视为陈旧。对此方法的响应不可缓存。

TRACE

此方法调用请求消息的远程应用层环回。请求的最终接收者应将收到的消息作为 200 (OK) 响应的实体主体反射回客户端。最终接收者是源服务器,或第一个在请求中接收到 Max-Forwards 值为 0 的代理或网关。TRACE 请求不得包含实体。

对此方法的响应绝不能被缓存。