代理软件包存储库的最佳实践


16

我的公司网络中有一些CentOS服务器。出于安全原因,除非服务器是服务器的核心功能要求,否则大多数服务器都不具有常规的出站Internet访问权限。

当我需要更新软件包时,这会带来挑战。对于yum存储库,我目前从Internet镜像所有需要的存储库,并使这些镜像在Intranet内部可用。我在以下五个环境中的每个环境中保留每个回购的副本:开发,质量保证,登台和两个生产数据中心。

我目前不解决特定于语言的软件包存储库。当服务器需要rubygems,PyPI,PECL,CPAN或npm的更新时,它们必须获得临时出站Internet访问以获取软件包。我被要求开始镜像rubygems和PyPI,其余的可能会跟随。

所有这些都是笨拙的,不能很好地工作。我想用一个环境中的单个缓存代理和其他环境中的四个菊花链代理替换它,以消除完整镜像的复杂性和磁盘开销。另外:

  • 它可以是正向或反向代理。每个程序包管理器都支持代理服务器或自定义存储库终结点,它们可以是本地镜像或反向代理。
  • 它需要精细的访问控制,因此我可以限制哪些客户端IP可以连接到哪些存储库域。
  • 客户端需要能够跟随重定向到未知域。您最初的请求可能仅限于rubygems.org,但是如果该服务器将302返回给随机CDN,则您应该可以遵循它。
  • 它应该支持HTTPS后端。我不一定需要模拟其他SSL服务器,但是我应该能够通过HTTP重新公开HTTPS站点,或者终止并使用其他证书重新加密。

我最初查看反向代理,而Varnish似乎是唯一允许我内部解析代理中的302重定向的代理。但是,免费版本的Varnish不支持HTTPS后端。我现在正在评估Squid作为前向代理选项。

在企业网络中,这似乎应该是一个相对普遍的问题,但是我很难找到其他人如何解决此问题的示例。有没有人实施过类似的方法或对如何做到最好有想法?

谢谢!

Answers:


5

我们为此使用鱿鱼;鱿鱼的好处是,您可以很容易地根据模式匹配设置对象的单个到期时间,从而可以相当快地清除yum存储库中的元数据。我们拥有的配置可以实现以下目的:

refresh_pattern (Release|Packages(.gz)*)$      0       20%     2880
refresh_pattern (\.xml|xml\.gz)$      0       20%     2880
refresh_pattern ((sqlite.bz2)*)$      0       20%     2880
refresh_pattern (\.deb|\.udeb)$   1296000 100% 1296000
refresh_pattern (\.rpm|\.srpm)$   1296000 100% 1296000
refresh_pattern .        0    20%    4320

http://www.squid-cache.org/Doc/config/refresh_pattern/


5

这是代理的确定用例。普通代理,而不是反向代理(又称负载均衡器)。

最著名,免费和开源的是squid。幸运的是,它是少数几个可以轻松安装apt-get install squid3为一个单一文件并配置为一个文件的优秀开源软件之一/etc/squid3/squid.conf

我们将介绍一些好的实践和经验教训。

官方配置文件略有修改(删除了5000条无用的注释行)。

#       WELCOME TO SQUID 3.4.8
#       ----------------------------
#
#       This is the documentation for the Squid configuration file.
#       This documentation can also be found online at:
#               http://www.squid-cache.org/Doc/config/
#
#       You may wish to look at the Squid home page and wiki for the
#       FAQ and other documentation:
#               http://www.squid-cache.org/
#               http://wiki.squid-cache.org/SquidFaq
#               http://wiki.squid-cache.org/ConfigExamples
#

###########################################################
# ACL
###########################################################

acl SSL_ports port 443
acl Safe_ports port 80          # http
acl Safe_ports port 21          # ftp
acl Safe_ports port 443         # https
acl Safe_ports port 1025-65535  # unregistered ports

acl CONNECT method CONNECT

#####################################################
# Recommended minimum Access Permission configuration
#####################################################
# Deny requests to certain unsafe ports
http_access deny !Safe_ports

# Deny CONNECT to other than secure SSL ports
http_access deny CONNECT !SSL_ports

# Only allow cachemgr access from localhost
http_access allow localhost manager
http_access deny manager

#####################################################
# ACL
#####################################################

# access is limited to our subnets
acl mycompany_net   src 10.0.0.0/8

# access is limited to whitelisted domains
# ".example.com" includes all subdomains of example.com
acl repo_domain dstdomain .keyserver.ubuntu.com
acl repo_domain dstdomain .debian.org
acl repo_domain dstdomain .python.org

# clients come from a known subnet AND go to a known domain
http_access allow repo_domain mycompany_net

# And finally deny all other access to this proxy
http_access deny all

#####################################################
# Other
#####################################################

# default proxy port is 3128
http_port 0.0.0.0:3128

# don't forward internal private IP addresses
forwarded_for off

# disable ALL caching
# bandwidth is cheap. debugging cache related bugs is expensive.
cache deny all

# logs
# Note: not sure if squid configures logrotate or not
access_log daemon:/var/log/squid3/access.log squid
access_log syslog:squid.INFO squid


# leave coredumps in the first cache dir
coredump_dir /var/spool/squid3

# force immediaty expiry of items in the cache.
# caching is disabled. This setting is set as an additional precaution.
refresh_pattern .               0       0%      0

客户端配置-环境变量

在所有系统上配置这两个环境变量。

http_proxy=squid.internal.mycompany.com:3128
https_proxy=squid.internal.mycompany.com:3128

大多数http客户端库(libcurl,httpclient等)都是使用环境变量自行配置的。大多数应用程序都使用一种常见的库,因此支持开箱即用的代理(开发人员不必知道它们确实在这样做)。

注意语法是严格的:

  1. http_proxy在大多数Linux上,变量名必须小写。
  2. 变量值不得开头http(s)://(代理协议不是http(s))。

客户端配置-特定

一些应用程序在设置变量之前会忽略环境变量和/或将其作为服务运行(例如debian apt)。

这些应用程序将需要特殊的配置(例如/etc/apt.conf)。

HTTPS代理-连接

设计完全支持HTTPS代理。它使用一种特殊的“ CONNECT”方法,该方法在浏览器和代理之间建立某种隧道。

邓诺(Dunno)对此事有很多看法,但多年来我从未对此有任何疑问。它只是工作。

HTTPS特例-透明代理

关于透明代理的说明。(即,代理是隐藏的,它会拦截客户端的请求。中间人)。

透明代理正在破坏HTTPS。客户端不知道有代理,也没有理由使用特殊的Connect方法。

客户端尝试直接HTTPS连接...被拦截。检测到拦截并在整个地方引发错误。(HTTPS旨在检测中间人攻击)。

域和CDN白名单

squid完全支持域和子域白名单。但是,它一定会不时以意外的方式失败。

现代网站可以具有各种域重定向和CDN。当人们不花大力气将所有内容整齐地放在一个域中时,这将破坏ACL。

有时会有一个安装程序或软件包想要在运行前调用该家庭作业或检索外部依赖项。它每次都会失败,您对此无能为力。

快取

提供的配置文件将禁用所有形式的缓存。安全胜过遗憾。

就我个人而言,此刻我正在云中运行事物,所有实例均具有至少100 Mbps的连接性,并且提供商为自动发现的流行内容(例如Debian)运行自己的存储库。这使得带宽成为我所不关心的商品。

我宁愿完全禁用缓存,也不愿遇到一个单个的缓存错误,该错误会使我的大脑在故障排除中融为一体。互联网上的每个人都无法正确获取其缓存标题。

但是,并非所有环境都有相同的要求。您可能需要付出更多努力并配置缓存。

从来不需要在代理上进行身份验证

有一个选项要求客户端(通常使用其LDAP帐户)进行密码身份验证。它将破坏Universe中的所有浏览器和所有命令行工具。

如果要在代理上进行身份验证,请不要。

如果管理人员需要身份验证,请说明这是不可能的。

如果您是一名开发人员,而您刚刚加入了一家阻止直接互联网并强制进行代理身份验证的公司,则可以逃之WAY。

结论

我们经历了常见的配置,常见的错误以及关于代理必须知道的事情。

学习到教训了:

  • 有一个很好的开源软件用于代理(鱿鱼)
  • 配置简单容易(一个短文件)
  • 所有(可选)安全措施都需要权衡
  • 最高级的选项会破坏内容并再次困扰您
  • 透明代理正在破坏HTTPS
  • 代理身份验证是邪恶的

与编程和系统设计一样,管理需求和期望至关重要。

在设置代理服务器时,我建议您坚持基本操作。一般来说,没有任何特殊过滤的纯代理将很好地工作,并且不会带来任何麻烦。只是要记住(自动)配置客户端。


s / man-in-he-middle / man-in-the-middle /(S / E禁止单个字符编辑)
Chen Levy

4

这不能解决您的所有任务,但是也许仍然有用。尽管名称如此,apt-cacher-ng不仅适用于Debian和衍生产品,而且

缓存代理。专门用于Linux发行商的软件包文件,主要用于Debian(和基于Debian的)发行版,但不仅限于此。

我正在像您这样的类似(基于Debian的)环境中的生产环境中使用它。

但是,AFAIK不支持rubygems,PyPI,PECL,CPAN或npm,并且不提供粒状ACL。

我个人认为,调查Squid是个好主意。如果最后实施设置,能否请您分享一下经验?我对它的发展非常感兴趣。


2

我们遇到了类似的挑战,并已使用本地存储库和基于快照的存储系统解决了该问题。我们基本上会更新开发存储库,将其克隆以进行测试,将其克隆以进行登台,最后进行生产。这样就限制了磁盘的使用量,而且所有的sata存储都很慢,没关系。

客户端从我们的配置管理中获取存储库信息,因此在必要时进行切换很容易。

您可以在代理服务器上使用用户代理字符串或源ips /掩码组合并限制它们对某些域的访问来使用ace来实现所需的功能,但是如果您这样做,我会看到一个问题,即软件包/库的不同版本。因此,如果其中一台主机可以访问cpan并请求模块xxx :: yyy,除非客户端指示使用特定版本,否则将从cpan(或pypy或rubygems)中获取最新版本,而该cpan可能已经存在,也可能不是缓存在代理中。因此,您可能最终在同一环境中使用不同版本。如果您使用本地存储库,则不会有此问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.