GithubHelp home page GithubHelp logo

[shares] usage and demos about natmap HOT 12 OPEN

heiher avatar heiher commented on May 20, 2024
[shares] usage and demos

from natmap.

Comments (12)

Mythologyli avatar Mythologyli commented on May 20, 2024 8

今天刚写的 qBittorrent 打洞脚本,可能不太完善,欢迎大家反馈:
https://github.com/Mythologyli/qBittorrent-NAT-TCP-Hole-Punching

from natmap.

OpportunityLiu avatar OpportunityLiu commented on May 20, 2024 3

尝试实现了 NAT-PMP 协议给 Transmission 用 ,但是它的支持好像有问题,给他返回映射端口后,它把 IPv6 的监听端口也改了,导致 IPv6 入站全被防火墙拦截了。。。
应该没问题,就是一时没有v6入站

https://github.com/OpportunityLiu/nat-mapmp

image

image

from natmap.

wy580477 avatar wy580477 commented on May 20, 2024 2

TCP 打洞部署 Vmess TCP 代理服务 让流量回家,通过脚本生成 vmess 分享链接保持更新。

对比 wireguard 优点:

  1. 几乎所有的翻墙代理客户端都可以支持,无需安装专用改版客户端。
  2. Vmess 服务端部署更简单更轻量,只需要运行代理服务端程序即可,无需任何系统特权修改系统设置。
  3. TCP 协议传输,可以解决某些网络环境下 UDP 被限制的问题。

SIng-box 服务端 Vmess 配置示例:

{
  "log": {
    "level": "info"
  },
  "inbounds": [
    {
      "type": "vmess",
      "listen": "0.0.0.0",
      "listen_port": 9689,
      "users": [
        {
          "uuid": "20a46c57-710e-4ec9-947d-2c178f037bf5",
          "alterId": 0
        }
      ],
      "sniff": true,
      "sniff_override_destination": false
    }
  ]
}

配合 natmap 的 linux 脚本(需要 base64 命令,openwrt 通过 opkg install coreutils-base64 安装):

#!/bin/sh

# 服务器别名
server_alias=Home_Proxy

# 服务器地址
server_address="$1"

# 服务器端口
server_port="$2"

# 用户 UUID
user_id="20a46c57-710e-4ec9-947d-2c178f037bf5"

# 生成的 Vmess 分享链接文件位置
share_link_file="/www/ad874236-07ed-4801-99f0"


# 生成 VMess 链接
vmess_link="vmess://$(echo -n "{\"v\":\"2\",\"ps\":\"$server_alias\",\"add\":\"$server_address\",\"port\":$server_port,\"id\":\"$user_id\",\"aid\":\"0\",\"net\":\"tcp\",\"type\":\"none\"}" | base64 -w 0)"

echo $vmess_link > $share_link_file

生成的 分享链接 文件可以通过 内网穿透 或者 增加 curl 命令上传至 web 服务暴露出来。
然后代理客户端,将 url 地址填入订阅功能即可。

注意:

  1. 生成的订阅文件一定要使用复杂不规律文件名/路径,而且订阅 url 一定要用 https 加密保证安全。
  2. 代理客户端可能默认局域网地址段直连,这时需要在代理客户端路由功能中把家里局域网 ip 段设置为走代理。
  3. 多人使用的情况下,可以通过代理服务端的路由功能,限制对内网地址段的访问。

from natmap.

EkkoG avatar EkkoG commented on May 20, 2024 1

使用NATMap在NAT-1私网IP宽带上部署 Trojan 服务,并通过其访问内网服务(回家)

from natmap.

heyeshuang avatar heyeshuang commented on May 20, 2024 1

对于wireguard方式,写了一个PowerShell脚本,能够自动修改配置文件的Endpoint并调用wireguard.exe进行连接。

使用方法:

  1. 安装wireguard-windows,用客户端连接测试成功。
  2. 在文件夹C:\example下建立wg.ps1nat.conf,粘贴Gist内容。
  3. 按照实际情况修改nat.conf,以及wg.ps1$Hostname部分。Endpoint不必修改。
  4. 以管理员身份运行PowerShell
  5. 设置ps1脚本运行权限:Set-ExecutionPolicy RemoteSigned(或Unrestricted)
  6. 启动Wireguard:C:\example\wg.ps1 -up
  7. 停止Wireguard:C:\example\wg.ps1 -down

在Windows 11, Powershell 5.1.22621.963测试通过,也可以配合Windows下的sudo使用。

另外,在Android下,也可以用termux运行nm-echo.sh来获得IP地址,可以不必更换客户端。

from natmap.

OpenGG avatar OpenGG commented on May 20, 2024 1

Resolve IP4P and generate config with cloudflare worker.

worker.js:

/**
 * Purpose: Resolve IP4P and generate a configuration using a Cloudflare worker.
 * 
 * Usage:
 * 1. Create an online configuration file with placeholders: ${ip4p.ip}, ${ip4p.port}, ${query.xxx}.
 * 2. Set your online configuration URL as the CONFIG_URL variable and publish this script as a Cloudflare worker.
 * 3. Retrieve your generated configuration by accessing https://YOUR-WORKER.workers.dev/YOUR-random-PATH-12435/clash?IP4P_DOMAIN=YOUR_IP4P_DOMAIN&cipher=YOUR_CIPHER&password=YOUR_PASSWORD.
 * 4. Additional keyword checks to the user-agent header can be applied, by setting ALLOW_UA_KEYWORDS.
 * 
 * Notes:
 * 1. Only IP4P_DOMAIN is mandatory; the rest of the query parameters are optional.
 * 2. The configuration itself can be in any format you like (yaml, json, etc.).
 * 3. Add ?_= to the CONFIG_URL to prevent caching.
 * 4. Choose a random PATH to prevent URL leakage.
 * 5. If the worker's domain is blocked in your region, consider binding the worker to your custom domain.
 */

// Set your online configuration URL here
const CONFIG_URL = 'https://gist.githubusercontent.com/YOUR_ONLINE_CONFIG/config-ss.yaml?_=';

// Choose a random path to prevent URL leakage
const PATH = '/YOUR-random-PATH-12435/clash';

// Keywords to allow in user-agent header
// const ALLOW_UA_KEYWORDS = 'clash,Clash,v2ray'
const ALLOW_UA_KEYWORDS = ''

// Cloudflare DNS-over-HTTPS URL
const DOH_URL = 'https://cloudflare-dns.com/dns-query?ct=application/dns-json';

const ALLOW_UA_KEYWORDS_ARR = ALLOW_UA_KEYWORDS.split(',')
  .filter(keyword => keyword)

/**
 * Performs an HTTP GET request.
 * 
 * @param {string | URL} url - The URL to fetch.
 * @returns {Promise<Response>} A promise that resolves to the fetch response.
 */
const get = async (url) => {
  const res = await fetch(url)

  if (!res.ok) {
    throw new Error(`Request error: ${res.status}`)
  }

  return res
}

/**
 * Resolves DNS records using DNS-over-HTTPS.
 * 
 * @param {string} domain - The domain to resolve.
 * @param {string} [type='AAAA'] - The DNS record type (default: 'AAAA').
 * @returns {Promise<Object>} A promise that resolves to the DNS response JSON object.
 */
const resolveDNSRecord = async (domain, type = 'AAAA') => {
  const url = new URL(DOH_URL)

  url.searchParams.append('name', domain)
  url.searchParams.append('type', type)

  const res = await get(url)

  return res.json()
}

/**
 * @typedef {Object} IP4PInfo
 * @property {string} ip - The IP address.
 * @property {number} port - The port number.
 */

/**
 * Resolves IP4P information from DNS records.
 *
 * @param {string} domain - The domain to resolve IP4P for.
 * @returns {Promise<IP4PInfo>} A promise that resolves to an object containing IP and port.
 * @throws {Error} If the IP4P information is invalid.
 */
const resolveIP4P = async (domain) => {
  const json = await resolveDNSRecord(domain)

  const answer = json?.Answer

  if (!answer || !Array.isArray(answer)) {
    throw new Error('Invalid dns record')
  }

  const data = answer.find(t => t.data)?.data || ''

  const parts = data.split(':')
  if (parts.length !== 5) {
    throw new Error(`Invalid IP4P: ${data}`)
  }

  // See: https://github.com/heiher/natmap/wiki/ssh#proxycommand

  const port = parseInt(parts[2], 16)
  const ipab = parseInt(parts[3], 16)
  const ipcd = parseInt(parts[4], 16)

  if (Number.isNaN(port) || Number.isNaN(ipab) || Number.isNaN(ipcd)) {
    throw new Error(`Invalid IP4P values: ${data}`)
  }

  const ipa = ipab >> 8
  const ipb = ipab & 0xff
  const ipc = ipcd >> 8
  const ipd = ipcd & 0xff

  const ip = `${ipa}.${ipb}.${ipc}.${ipd}`

  return {
    ip,
    port,
  }
}

/**
 * Gets the configuration from the online source with placeholders replaced.
 *
 * @param {string} url - The URL of the configuration source.
 * @param {(type: string, key: string) => string | undefined} replacer - A function that replaces placeholders based on their type and key.
 * @returns {Promise<string>} A promise that resolves to the configuration with placeholders replaced.
 */
const getConfig = async (url, replacer) => {
  const urlObject = new URL(url)
  const {
    searchParams,
  } = urlObject

  if (searchParams.has('_')) {
    searchParams.set('_', `${Math.random()}`)
  }

  const res = await get(urlObject)

  const configText = await res.text()

  return configText.replace(/\$\{([^}]+)\}/g, (g0, g1) => {
    const index = g1.indexOf('.')
    if (index === -1) {
      return g0
    }

    const type = g1.slice(0, index)

    const key = g1.slice(index + 1)

    const value = replacer(type, key)

    if (typeof value === 'string') {
      return value
    }

    return g0
  })
}

/**
 * Checks if the user-agent header is allowed.
 *
 * @param {string} ua - The user-agent header.
 * @returns {boolean} True if user-agent is allowed, false otherwise.
 */
const allowUA = (ua) => {
  if (ALLOW_UA_KEYWORDS_ARR.length === 0) {
    return true
  }

  return ALLOW_UA_KEYWORDS_ARR.some(keyword => ua.includes(keyword))
}

/**
 * Main function to handle requests.
 *
 * @param {Request} request - The request object.
 * @returns {Promise<string>} A promise that resolves to the response.
 * @throws {Error}
 */
const main = async (request) => {
  const {
    url,
    headers,
  } = request

  const ua = headers.get('user-agent')

  if (!allowUA(ua)) {
    throw new Error('Invalid user-agent, failed to pass keyword checking')
  }

  const {
    pathname,
    searchParams,
  } = new URL(url)

  if (pathname !== PATH) {
    throw new Error(`Unknown request: ${pathname}`)
  }

  const domain = searchParams.get('IP4P_DOMAIN')

  if (!domain) {
    throw new Error('Domain name not provided')
  }

  const ip4p = await resolveIP4P(domain)

  const config = await getConfig(CONFIG_URL, (type, key) => {
    if (type === 'ip4p' && (key === 'ip' || key === 'port')) {
      return `${ip4p[key]}`
    } else if (type === 'query') {
      return searchParams.get(key) || ''
    }

    return undefined;
  })

  return config
}

// Cloudflare worker export
export default {
  /**
   * Cloudflare Worker Fetch Function.
   *
   * @param {Request} request - The incoming request object.
   * @param {Object} env - The environment object.
   * @param {Object} ctx - The context object.
   * @returns {Promise<Response>} A promise that resolves to the response.
   */
  async fetch(request, env, ctx) {
    try {
      const content = await main(request)

      return new Response(content, {
        status: 200,
        headers: {
          'cache-control': 'no-cache, no-store'
        }
      })
    } catch (e) {
      console.error(e)

      return new Response('', {
        status: 404,
        headers: {
          'cache-control': 'no-cache, no-store'
        }
      })
    }
  },
}

Config file (can be yaml, json, whatever format you like):

mixed-port: 7890

mode: rule

ipv6: true
dns:
  ipv6: true

proxies:
  -
    name: proxy-server
    type: ss
    server: ${ip4p.ip}
    port: ${ip4p.port}
    cipher: "${query.cipher}"
    password: "${query.password}"
    udp: true

proxy-groups:
  -
    name: PROXY
    type: select
    proxies:
      - proxy-server
      - DIRECT

rule-providers:
  reject:
    type: http
    behavior: domain
    url: "https://ghproxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/reject.txt"
    path: ./ruleset/reject.yaml
    interval: 86400

  private:
    type: http
    behavior: domain
    url: "https://ghproxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/private.txt"
    path: ./ruleset/private.yaml
    interval: 86400

  gfw:
    type: http
    behavior: domain
    url: "https://ghproxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/gfw.txt"
    path: ./ruleset/gfw.yaml
    interval: 86400

  tld-not-cn:
    type: http
    behavior: domain
    url: "https://ghproxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/tld-not-cn.txt"
    path: ./ruleset/tld-not-cn.yaml
    interval: 86400

  telegramcidr:
    type: http
    behavior: ipcidr
    url: "https://ghproxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/telegramcidr.txt"
    path: ./ruleset/telegramcidr.yaml
    interval: 86400

  applications:
    type: http
    behavior: classical
    url: "https://ghproxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/applications.txt"
    path: ./ruleset/applications.yaml
    interval: 86400

rules:
  - RULE-SET,applications,DIRECT
  - RULE-SET,private,DIRECT
  - RULE-SET,reject,REJECT
  - RULE-SET,tld-not-cn,PROXY
  - RULE-SET,gfw,PROXY
  - RULE-SET,telegramcidr,PROXY
  - MATCH,DIRECT

from natmap.

xream avatar xream commented on May 20, 2024 1

image

https://github.com/sub-store-org/Sub-Store 的节点域名解析支持了 IP4P

from natmap.

heiher avatar heiher commented on May 20, 2024

TCP

UDP

from natmap.

wits-fe avatar wits-fe commented on May 20, 2024

uTorrent / qBittorrent / Transmisson 自动更新端口脚本

from natmap.

xream avatar xream commented on May 20, 2024

clash.meta(mihomo) 已支持 IP4P 出站

感谢 亚托莉佬以及 mihomo 开发组接受我的建议(

用法: 开启 IPv6, 在需要使用的地方配置 IP4P 域名.

IP4P 节点和 ip4p.web.com 这个服务可以正常使用

ipv6: true
dns:
  ipv6: true
experimental:
  dialer-ip4p-convert: true
proxies:
  - name: IP4P
    server: ip4p.proxy.com
    port: 1
    ...
rules:
  - DOMAIN,ip4p.web.com,DIRECT

from natmap.

xream avatar xream commented on May 20, 2024

IP4P 请求自动重定向(以 Surge 为例)

效果为 访问 http://ip4p.com/a?v=1 时, 自动根据 IP4P 信息重定向为 http://1.1.1.1:1234/a?v=1

使用场景

使用固定的 URL 访问 STUN 打洞的内网服务

模块和脚本见 https://t.me/zhetengsha/1198

from natmap.

heyeshuang avatar heyeshuang commented on May 20, 2024

TCP 打洞部署 Vmess TCP 代理服务 让流量回家,通过脚本生成 vmess 分享链接保持更新。

可以利用自部署的pastebin服务,例如SharzyL/pastebin-worker,来提供分享链接,不必暴露自己的web服务。

配合 natmap 的 linux 脚本(也需要 base64 命令):

#!/bin/bash

ip_address="${1}"
port="${2}"
pastebin_url="https://shz.al/"
pastebin_name="<随机字符串a>"
pb_pass="<随机字符串b>"
raw_ss_url="ss://2022-blake3-aes-128-gcm:<密码>@${ip_address}:${port}#ss-home4
ss://2022-blake3-aes-128-gcm:<密码>@<其他地址>#ss-home6
"

# Apply base64 encoding
base64_encoded=$(echo -n "${raw_ss_url}" | base64 -w 0)

# Upload the result using curl
curl -Fc="${base64_encoded}" -Fe="24M" -Fs="${pb_pass}" -Fn="${pastebin_name}" "${pastebin_url}"
curl -X PUT -Fc="${base64_encoded}" -Fe="24M" "${pastebin_url}~${pastebin_name}:${pb_pass}"

然后就可以用https://shz.al/~<随机字符串a>作为订阅地址了。

from natmap.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.