首页 > 其他分享 >搭建专属Docker镜像中转站

搭建专属Docker镜像中转站

时间:2024-12-08 19:42:42浏览次数:3  
标签:REGEX url request headers PROXY new 镜像 Docker 中转站

阅读之前

请注意:实现搭建docker镜像中转,需要满足以下条件,如不满足请不要复现浪费时间。

  1. 拥有一个自己的域名
  2. 域名通过cloudflare的DNS进行解析,可以在cloudflar中阅读帮助进行解析

注册并登录CF账号

https://dash.cloudflare.com/login?lang=zh-hans-cn

建立worker

  1. 创建worker
    alt text

  2. 配置worker
    alt text

  3. 开始编辑代码
    alt text

  4. 编辑代码
    在左侧代码去执行:
    alt text

  • 删除全部默认代码
  • 添加以下代码
function logError(request, message) {
  console.error(
    `${message}, clientIp: ${request.headers.get(
      "cf-connecting-ip"
    )}, user-agent: ${request.headers.get("user-agent")}, url: ${request.url}`
  );
}

function createNewRequest(request, url, proxyHostname, originHostname) {
  const newRequestHeaders = new Headers(request.headers);
  for (const [key, value] of newRequestHeaders) {
    if (value.includes(originHostname)) {
      newRequestHeaders.set(
        key,
        value.replace(
          new RegExp(`(?<!\\.)\\b${originHostname}\\b`, "g"),
          proxyHostname
        )
      );
    }
  }
  return new Request(url.toString(), {
    method: request.method,
    headers: newRequestHeaders,
    body: request.body,
  });
}

function setResponseHeaders(
  originalResponse,
  proxyHostname,
  originHostname,
  DEBUG
) {
  const newResponseHeaders = new Headers(originalResponse.headers);
  for (const [key, value] of newResponseHeaders) {
    if (value.includes(proxyHostname)) {
      newResponseHeaders.set(
        key,
        value.replace(
          new RegExp(`(?<!\\.)\\b${proxyHostname}\\b`, "g"),
          originHostname
        )
      );
    }
  }
  if (DEBUG) {
    newResponseHeaders.delete("content-security-policy");
  }
  let docker_auth_url = newResponseHeaders.get("www-authenticate");
  if (docker_auth_url && docker_auth_url.includes("auth.docker.io/token")) {
    newResponseHeaders.set(
      "www-authenticate",
      docker_auth_url.replace("auth.docker.io/token", originHostname + "/token")
    );
  }
  return newResponseHeaders;
}

/**
 * 替换内容
 * @param originalResponse 响应
 * @param proxyHostname 代理地址 hostname
 * @param pathnameRegex 代理地址路径匹配的正则表达式
 * @param originHostname 替换的字符串
 * @returns {Promise<*>}
 */
async function replaceResponseText(
  originalResponse,
  proxyHostname,
  pathnameRegex,
  originHostname
) {
  let text = await originalResponse.text();
  if (pathnameRegex) {
    pathnameRegex = pathnameRegex.replace(/^\^/, "");
    return text.replace(
      new RegExp(`((?<!\\.)\\b${proxyHostname}\\b)(${pathnameRegex})`, "g"),
      `${originHostname}$2`
    );
  } else {
    return text.replace(
      new RegExp(`(?<!\\.)\\b${proxyHostname}\\b`, "g"),
      originHostname
    );
  }
}

async function nginx() {
  return `<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>`;
}

export default {
  async fetch(request, env, ctx) {
    try {
      let {
        PROXY_HOSTNAME = "registry-1.docker.io",
        PROXY_PROTOCOL = "https",
        PATHNAME_REGEX,
        UA_WHITELIST_REGEX,
        UA_BLACKLIST_REGEX,
        URL302,
        IP_WHITELIST_REGEX,
        IP_BLACKLIST_REGEX,
        REGION_WHITELIST_REGEX,
        REGION_BLACKLIST_REGEX,
        DEBUG = false,
      } = env;
      const url = new URL(request.url);
      const originHostname = url.hostname;
      if (url.pathname.includes("/token")) {
        PROXY_HOSTNAME = "auth.docker.io";
      } else if (url.pathname.includes("/search")) {
        PROXY_HOSTNAME = "index.docker.io";
      }
      if (
        !PROXY_HOSTNAME ||
        (PATHNAME_REGEX && !new RegExp(PATHNAME_REGEX).test(url.pathname)) ||
        (UA_WHITELIST_REGEX &&
          !new RegExp(UA_WHITELIST_REGEX).test(
            request.headers.get("user-agent").toLowerCase()
          )) ||
        (UA_BLACKLIST_REGEX &&
          new RegExp(UA_BLACKLIST_REGEX).test(
            request.headers.get("user-agent").toLowerCase()
          )) ||
        (IP_WHITELIST_REGEX &&
          !new RegExp(IP_WHITELIST_REGEX).test(
            request.headers.get("cf-connecting-ip")
          )) ||
        (IP_BLACKLIST_REGEX &&
          new RegExp(IP_BLACKLIST_REGEX).test(
            request.headers.get("cf-connecting-ip")
          )) ||
        (REGION_WHITELIST_REGEX &&
          !new RegExp(REGION_WHITELIST_REGEX).test(
            request.headers.get("cf-ipcountry")
          )) ||
        (REGION_BLACKLIST_REGEX &&
          new RegExp(REGION_BLACKLIST_REGEX).test(
            request.headers.get("cf-ipcountry")
          ))
      ) {
        logError(request, "Invalid");
        return URL302
          ? Response.redirect(URL302, 302)
          : new Response(await nginx(), {
              headers: {
                "Content-Type": "text/html; charset=utf-8",
              },
            });
      }
      url.host = PROXY_HOSTNAME;
      url.protocol = PROXY_PROTOCOL;
      const newRequest = createNewRequest(
        request,
        url,
        PROXY_HOSTNAME,
        originHostname
      );
      const originalResponse = await fetch(newRequest);
      const newResponseHeaders = setResponseHeaders(
        originalResponse,
        PROXY_HOSTNAME,
        originHostname,
        DEBUG
      );
      const contentType = newResponseHeaders.get("content-type") || "";
      let body;
      if (contentType.includes("text/")) {
        body = await replaceResponseText(
          originalResponse,
          PROXY_HOSTNAME,
          PATHNAME_REGEX,
          originHostname
        );
      } else {
        body = originalResponse.body;
      }
      return new Response(body, {
        status: originalResponse.status,
        headers: newResponseHeaders,
      });
    } catch (error) {
      logError(request, `Fetch error: ${error.message}`);
      return new Response("Internal Server Error", { status: 500 });
    }
  },
};
  • 点击右上角“部署”
  • 点击左上角向前返回

设置worker

  1. 设置选项
    alt text
  2. 添加自己的域名
    alt text

配置docker镜像

  1. 在目标服务器配置docker镜像下载站
vi /etc/docker/daemon.json

在"registry-mirrors"字段添加自己的域名

  1. 拉取镜像测试
    docker pull redis

标签:REGEX,url,request,headers,PROXY,new,镜像,Docker,中转站
From: https://www.cnblogs.com/ybli/p/18593460

相关文章

  • Ubuntu24离线安装docker
    一、为什么要离线安装docker使用二进制发行包离线安装Docker的主要原因是针对特定行业的云平台,如地方政务云、教育云或其他特种行业云平台,这些平台上的云主机往往由于安全政策或网络隔离的要求,无法直接访问互联网。因此,通过下载Docker的二进制发行包并进行离线安装,可以确保在这些......
  • Docker 的基本概念和优势
    Docker是一个开源的应用容器引擎,它可以让开发者将应用程序及其依赖项打包到一个容器中,并以轻量级、可移植的方式进行部署、运行和管理。Docker的基本概念包括镜像、容器和仓库。镜像(Image):镜像是一个只读的模板,包含了运行一个应用程序所需的依赖项和配置文件。镜像可以根据Doc......
  • Docker 逃逸突破边界
    免责声明本博客文章仅供教育和研究目的使用。本文中提到的所有信息和技术均基于公开来源和合法获取的知识。本文不鼓励或支持任何非法活动,包括但不限于未经授权访问计算机系统、网络或数据。作者对于读者使用本文中的信息所导致的任何直接或间接后果不承担任何责任。包括但不......
  • 【Docker】创建Docker并部署Web站点
    要在服务器上创建Docker容器,并在其中部署站点,你可以按照以下步骤操作。我们将以Flask应用为例来说明如何完成这一过程。1.准备工作确保你的服务器已经安装了Docker。如果没有,请根据官方文档安装:Docker安装指南2.创建Flask应用的Dockerfile假设你已经有了一个Fla......
  • 21、使用Tomcat官方镜像部署War应用程序
    1.启动一个Tomcat容器,将Tomcat默认端口8080映射为8888dockerpulltomcat:8.0dockerimagestomcatdockerrun-d--rm-p8888:8080--namelgztomcattomcat:8.0192.168.20.19:8888[root@lgz19docker~]#vi/root/tomcat-users.xml<?xmlversion='1.0'encoding=&#......
  • Kali Linux超详细安装教程(附镜像)
    一、镜像获取(任选其一)1.kali官网http://old.kali.org/kali-images/http://old.kali.org/kali-images/kali-2021.1/kali-linux-2021.1-installer-amd64/​2.阿里镜像站https://mirrors.aliyun.com/kali-images/​3.(建议使用,速度快)通过网盘分享的文件:kali-linux-2......
  • 【mac】docker安装单节点elasticsearch
    【mac】docker安装单节点elastcsearch前言本文通过实操记录macbookM1pro上安装elasticsearch和kibana7.9.0的详细过程安装elasticsearch1、拉取dicker镜像dockerpullelasticsearch:7.9.1镜像拉取完成2、创建网络构建elasticsearch和kinbana的局域网,方便......
  • CentOS Docker 及 Docker Engine-Community 安装
    CentOSDocker安装Docker支持以下的64位CentOS版本:CentOS7CentOS8更高版本…使用官方安装脚本自动安装安装命令如下:curl-fsSLhttps://get.docker.com|bash-sdocker--mirrorAliyun手动安装卸载旧版本较旧的Docker版本称为docker或docker-eng......
  • 最强iOS手机免越狱群控系统:最新高清镜像投屏与多设备管理的新工具
    随着移动设备管理需求的不断增长,如何高效管理和优化多个iPhone或iPad设备成为了企业和个人用户面临的共同挑战。最新的苹果iOS免越狱手机群控系统提供了一种安全、便捷且高效的解决方案,适用于从自媒体运营到跨境电商等多个领域。本章将详细介绍这款系统的强大功能及其在不同应用场......
  • Docker图形化页面,DockerUI安装+使用
    公众号:泷羽Sec-尘宇安全前言DockerUI是一个易于使用且轻量级的docker管理工具。通过Web界面的操作,它方便不熟悉Docker指令的用户更快地使用Docker。方便后期的构建、管理并维护同时,它是完全开源和免费的。DockerUI具有易于使用的界面。它可以是用户不需要记住d......