Linux 下 iptables 双网卡 外网到内网端口转发

由于业务需要,服务器越来越多,内网服务器无外网环境管理甚是不便,所以折腾了一下外网到内网的端口转发以达到轻松管理的目的,贴一下心得。

S1:
eth0 10.0.0.1
eth1 x.x.x.x

S2:
eth0 10.0.0.2

S1 8082端口转发到内网机器22端口

iptables规则配置如下:

iptables -t nat -A PREROUTING -d x.x.x.x -p tcp --dport 8082 -j DNAT --to-destination 10.0.0.2:22
iptables -t nat -A POSTROUTING -d 10.0.0.2 -p tcp --dport 22 -j SNAT --to-source x.x.x.x
iptables -t nat -A PREROUTING -d "对外公网ip" -p tcp --dport "对外端口" -j DNAT --to "内部实际提供服务的ip":"实际提供服务的端口"
iptables -t nat -A POSTROUTING -d "内部实际提供服务的ip"-p tcp --dport "实际提供服务的端口" -j SNAT --to-source "运行iptables机器的内网ip"

PHP Bt种子转磁力链

include 'BEncode.php';
include 'BDecode.php';

$torrent_content = file_get_contents('filename.torrent');

$desc = BDecode($torrent_content);
$info = $desc['info'];
$hash = strtoupper(sha1( BEncode($info) ));

sprintf('magnet:?xt=urn:btih:%s&dn=%s', $hash, $info['name']);


BEncode.php

class BEncode {
    // Dictionary keys must be sorted. foreach tends to iterate over the order
    // the array was made, so we make a new one in sorted order. 🙂
    function makeSorted($array) {
        // Shouldn't happen!
        if (empty($array))
            return $array;
        $i = 0;
        foreach($array as $key => $dummy)
            $keys[$i++] = stripslashes($key);
        sort($keys);
        for ($i=0; isset($keys[$i]); $i++)
            $return[addslashes($keys[$i])] = $array[addslashes($keys[$i])];
        return $return;
    }

    // Encodes strings, integers and empty dictionaries.
    // $unstrip is set to true when decoding dictionary keys
    function encodeEntry($entry, &$fd, $unstrip = false) {
        if (is_bool($entry)) {
            $fd .= 'de';
            return;
        }
        if (is_int($entry) || is_float($entry)) {
            $fd .= 'i'.$entry.'e';
            return;
        }
        if ($unstrip)
            $myentry = stripslashes($entry);
        else
            $myentry = $entry;
        $length = strlen($myentry);
        $fd .= $length.':'.$myentry;
    }

    // Encodes lists
    function encodeList($array, &$fd) {
        $fd .= 'l';
        // The empty list is defined as array();
        if (empty($array)) {
            $fd .= 'e';
            return;
        }
        for ($i = 0; isset($array[$i]); $i++)
            $this->decideEncode($array[$i], $fd);
        $fd .= 'e';
    }

    // Passes lists and dictionaries accordingly, and has encodeEntry handle
    // the strings and integers.
    function decideEncode($unknown, &$fd) {
        if (is_array($unknown)) {
            if (isset($unknown[0]) || empty($unknown))
                return $this->encodeList($unknown, $fd);
            else
                return $this->encodeDict($unknown, $fd);
        }
        $this->encodeEntry($unknown, $fd);
    }

    // Encodes dictionaries
    function encodeDict($array, &$fd) {
        $fd .= 'd';
        if (is_bool($array)) {
            $fd .= 'e';
            return;
        }
        // NEED TO SORT!
        $newarray = $this->makeSorted($array);
        foreach($newarray as $left => $right) {
            $this->encodeEntry($left, $fd, true);
            $this->decideEncode($right, $fd);
        }
        $fd .= 'e';
    }
}

function BEncode($array) {
    $string = '';
    $encoder = new BEncode;
    $encoder->decideEncode($array, $string);
    return $string;
}

BDecode.php

class BDecode {
    function numberdecode($wholefile, $offset) {
        // Funky handling of negative numbers and zero
        $negative = false;
        if ($wholefile[$offset] == '-') {
            $negative = true;
            $offset++;
        }
        if ($wholefile[$offset] == '0') {
            $offset++;
            if ($negative)
                return array(false);
            if ($wholefile[$offset] == ':' || $wholefile[$offset] == 'e')
                return array(0, ++$offset);
            return array(false);
        }
        $ret[0] = 0;
        for(;;) {
            if ($wholefile[$offset] >= '0' && $wholefile[$offset] <= '9') {
                $ret[0] *= 10;
                //Added 2005.02.21 - VisiGod
           //Changing the type of variable from integer to double to prevent a numeric overflow   
                settype($ret[0],'double');
                //Added 2005.02.21 - VisiGod
                $ret[0] += ord($wholefile[$offset]) - ord('0');
                $offset++;
            }   else if ($wholefile[$offset] == 'e' || $wholefile[$offset] == ':') {
                // Tolerate : or e because this is a multiuse function
                $ret[1] = $offset+1;
                if ($negative) {
                    if ($ret[0] == 0)
                        return array(false);
                    $ret[0] = - $ret[0];
                }
                return $ret;
            } else return array(false);
        }
    }

    function decodeEntry($wholefile, $offset=0) {
        if ($wholefile[$offset] == 'd')
            return $this->decodeDict($wholefile, $offset);
        if ($wholefile[$offset] == 'l')
            return $this->decodelist($wholefile, $offset);
        if ($wholefile[$offset] == 'i')
            return $this->numberdecode($wholefile, ++$offset);
        // String value: decode number, then grab substring

        $info = $this->numberdecode($wholefile, $offset);
        if ($info[0] === false)
            return array(false);
        $ret[0] = substr($wholefile, $info[1], $info[0]);
        $ret[1] = $info[1]+strlen($ret[0]);
        return $ret;
    }

    function decodeList($wholefile, $offset) {
        if ($wholefile[$offset] != 'l')
            return array(false);
        $offset++;
        $ret = array();
        for ($i=0;;$i++) {
            if ($wholefile[$offset] == 'e')
                break;
            $value = $this->decodeEntry($wholefile, $offset);
            if ($value[0] === false)
                return array(false);
            $ret[$i] = $value[0];
            $offset = $value[1];
        }
        // The empty list is an empty array. Seems fine.
        return array(0=>$ret, 1=>++$offset);
    }

    // Tries to construct an array
    function decodeDict($wholefile, $offset=0) {
        if ($wholefile[$offset] == 'l')
            return $this->decodeList($wholefile, $offset);
        if ($wholefile[$offset] != 'd')
            return false;
        $ret=array();
        $offset++;
        for (;;) {  
            if ($wholefile[$offset] == 'e')   {
                $offset++;
                break;
            }
            $left = $this->decodeEntry($wholefile, $offset);
            if (!$left[0])
                return false;
            $offset = $left[1];
            if ($wholefile[$offset] == 'd') {
                // Recurse
                $value = $this->decodedict($wholefile, $offset);
                if (!$value[0])
                    return false;
                $ret[addslashes($left[0])] = $value[0];
                $offset= $value[1];
                continue;
            }
            if ($wholefile[$offset] == 'l') {
                $value = $this->decodeList($wholefile, $offset);
                if (!$value[0] && is_bool($value[0]))
                    return false;
                $ret[addslashes($left[0])] = $value[0];
                $offset = $value[1];
                continue;
            }
            $value = $this->decodeEntry($wholefile, $offset);
            if ($value[0] === false)
                return false;
            $ret[addslashes($left[0])] = $value[0];
            $offset = $value[1];
        }
        return array(0=>(empty($ret)?true:$ret), 1=>$offset);
    }
}

function BDecode($wholefile) {
    $decoder = new BDecode;
    $return = $decoder->decodeEntry($wholefile);
    return $return[0];
}

PHP生成Ed2k(电驴)连接

function genEd2k($filepath) {

    $chunk_size = 9728000;

    $ed2khash = '';

    if (!is_file($filepath)) {
            trigger_error('file not found',E_USER_WARNING);
            return False;
        }
    $filesize = filesize($filepath);
    $filename = pathinfo($filepath, PATHINFO_BASENAME);

    if ($filesize <= $chunk_size) {
        $ed2khash = hash_file('md4', $filepath, true);
    } else {
        $_hash_str = '';
        $fp = fopen($filepath,'r');
        while (!feof($fp)) {
            $data = fread($fp, $chunk_size);
            $_hash_str .= hash('md4', $data, True);
        }
        fclose($fp);
        $ed2khash = hash('md4', $_hash_str);
    }

    return sprintf('ed2k://|file|%s|%s|%s', urlencode($filename), $filesize, strtoupper($ed2khash));
}

调用:

echo genEd2k(__DIR__.'/test.rar');
// 输出
// ed2k://|file|test.rar|4150800|4EB96EFD6600264ACB4FAE237C3F7895