โครงสร้างพื้นฐาน: เซิร์ฟเวอร์ใน Datacenter, ระบบปฏิบัติการ - Debian Squeeze, เว็บเซิร์ฟเวอร์ - Apache 2.2.16
สถานการณ์:
cusotmers ของเราใช้งานเซิร์ฟเวอร์สดทุกวันซึ่งทำให้ไม่สามารถทดสอบการปรับปรุงและปรับปรุงได้ ดังนั้นเราจึงต้องการทำซ้ำทราฟฟิก HTTP ขาเข้าบนเซิร์ฟเวอร์ที่ใช้งานจริงไปยังเซิร์ฟเวอร์ระยะไกลหนึ่งหรือหลายเครื่องแบบเรียลไทม์ ปริมาณการใช้งานจะต้องถูกส่งผ่านไปยังเว็บเซิร์ฟเวอร์ท้องถิ่น (ในกรณีนี้ Apache) และไปยังเซิร์ฟเวอร์ระยะไกล ดังนั้นเราสามารถปรับการกำหนดค่าและใช้รหัสที่แตกต่าง / อัปเดตบนเซิร์ฟเวอร์ระยะไกลสำหรับการเปรียบเทียบและเปรียบเทียบกับเซิร์ฟเวอร์สดปัจจุบัน ขณะนี้เว็บเซิร์ฟเวอร์กำลังฟังเพลงโดยประมาณ 60 พอร์ตเพิ่มเติมนอกเหนือจาก 80 และ 443 เนื่องจากโครงสร้างไคลเอนต์
คำถาม: การทำซ้ำนี้ไปยังเซิร์ฟเวอร์ระยะไกลหนึ่งหรือหลายเครื่องสามารถนำไปใช้อย่างไร
เราได้ลองแล้ว:
- agnoster โรเนียว - นี่จะต้องเปิดหนึ่งเซสชันต่อพอร์ตซึ่งไม่สามารถใช้ได้ ( https://github.com/agnoster/duplicator )
- kklis proxy - ส่งต่อทราฟฟิกไปยังรีโมตเซิร์ฟเวอร์เท่านั้น แต่จะไม่ส่งต่อไปยัง logh webserver ( https://github.com/kklis/proxy )
- iptables - DNAT จะส่งต่อปริมาณข้อมูลเท่านั้น แต่จะไม่ส่งต่อไปยังเว็บเซิร์ฟเวอร์ท้องถิ่น
- iptables - TEE ทำซ้ำเฉพาะกับเซิร์ฟเวอร์ในเครือข่ายท้องถิ่น -> เซิร์ฟเวอร์ไม่ได้อยู่ในเครือข่ายเดียวกันเนื่องจากโครงสร้างของดาต้าเซ็นเตอร์
- ทางเลือกที่แนะนำสำหรับคำถาม "การรับส่งข้อมูล TCP ซ้ำกับพร็อกซี" ที่ stackoverflow ( https://stackoverflow.com/questions/7247668/duplicate-tcp-traffic-with-a-proxy ) ดังที่กล่าวไว้ TEE ไม่ทำงานกับเซิร์ฟเวอร์ระยะไกลนอกเครือข่ายท้องถิ่น teeproxy ไม่สามารถใช้งานได้อีกต่อไป ( https://github.com/chrislusf/tee-proxy ) และเราไม่พบที่อื่น
- เราได้เพิ่มที่อยู่ IP ที่สอง (ซึ่งอยู่ในเครือข่ายเดียวกัน) และกำหนดให้กับ eth0: 0 (ที่อยู่ IP หลักถูกกำหนดให้กับ eth0) ไม่ประสบความสำเร็จในการรวม IP ใหม่หรืออินเตอร์เฟสเสมือน eth0: 0 กับฟังก์ชันหรือเส้นทาง iptables TEE
- ทางเลือกที่แนะนำสำหรับคำถาม "การรับส่งข้อมูล tcp ซ้ำ ๆ บนเดเบียนบีบ" ( ทำซ้ำการรับส่งข้อมูล TCP ขาเข้าบน Debian Squeeze ) ไม่สำเร็จ เซสชัน cat | nc (cat / tmp / prodpipe | nc 127.0.0.1 12345 และ cat / tmp / testpipe | nc 127.0.0.1 23456) ถูกขัดจังหวะหลังจากทุกคำขอ / เชื่อมต่อโดยไคลเอนต์โดยไม่มีการแจ้งเตือนหรือบันทึก Keepalive ไม่ได้เปลี่ยนสถานการณ์นี้ แพคเกจ TCP ไม่ได้ถูกขนส่งไปยังระบบระยะไกล
- ความพยายามเพิ่มเติมพร้อมกับตัวเลือกที่แตกต่างกันของ socat (HowTo: http://www.cyberciti.biz/faq/linux-unix-tcp-port-forwarding/ , https://stackoverflow.com/questions/9024227/duplicate-input- unix-stream-to-multiple-tcp-clients-using-socat ) และเครื่องมือที่คล้ายกันไม่สำเร็จเนื่องจากฟังก์ชั่น TEE ที่ให้มาจะเขียนถึง FS เท่านั้น
- แน่นอน googling และค้นหา "ปัญหา" หรือการตั้งค่านี้ก็ไม่ประสบความสำเร็จเช่นกัน
เราหมดตัวเลือกที่นี่
มีวิธีการปิดการบังคับใช้ "เซิร์ฟเวอร์ในเครือข่ายท้องถิ่น" ของฟังก์ชั่น TEE เมื่อใช้ IPTABLES หรือไม่
เป้าหมายของเราสามารถทำได้โดยการใช้ IPTABLES หรือ Routes ต่างกันหรือไม่?
คุณรู้จักเครื่องมือที่แตกต่างกันสำหรับจุดประสงค์นี้ซึ่งได้รับการทดสอบและใช้ได้กับสถานการณ์เฉพาะเหล่านี้หรือไม่?
มีแหล่งที่มาที่แตกต่างกันสำหรับ tee-proxy (ซึ่งจะตรงกับความต้องการของเราอย่างสมบูรณ์แบบ AFAIK)?
ขอบคุณล่วงหน้าสำหรับคำตอบของคุณ
----------
แก้ไข: 05.02.2014
นี่คือสคริปต์หลามซึ่งจะทำหน้าที่ตามที่เราต้องการ:
import socket
import SimpleHTTPServer
import SocketServer
import sys, thread, time
def main(config, errorlog):
sys.stderr = file(errorlog, 'a')
for settings in parse(config):
thread.start_new_thread(server, settings)
while True:
time.sleep(60)
def parse(configline):
settings = list()
for line in file(configline):
parts = line.split()
settings.append((int(parts[0]), int(parts[1]), parts[2], int(parts[3])))
return settings
def server(*settings):
try:
dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
dock_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
dock_socket.bind(('', settings[0]))
dock_socket.listen(5)
while True:
client_socket = dock_socket.accept()[0]
client_data = client_socket.recv(1024)
sys.stderr.write("[OK] Data received:\n %s \n" % client_data)
print "Forward data to local port: %s" % (settings[1])
local_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
local_socket.connect(('', settings[1]))
local_socket.sendall(client_data)
print "Get response from local socket"
client_response = local_socket.recv(1024)
local_socket.close()
print "Send response to client"
client_socket.sendall(client_response)
print "Close client socket"
client_socket.close()
print "Forward data to remote server: %s:%s" % (settings[2],settings[3])
remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
remote_socket.connect((settings[2], settings[3]))
remote_socket.sendall(client_data)
print "Close remote sockets"
remote_socket.close()
except:
print "[ERROR]: ",
print sys.exc_info()
raise
if __name__ == '__main__':
main('multiforwarder.config', 'error.log')
ความคิดเห็นที่จะใช้สคริปต์นี้: สคริปต์
นี้ส่งต่อพอร์ตโลคัลที่กำหนดค่าไว้จำนวนหนึ่งไปยังโลคัลเซิร์ฟเวอร์อื่นและเซิร์ฟเวอร์ซ็อกเก็ตระยะไกล
การกำหนดค่า:
เพิ่มลงในไฟล์ config-port.config ที่มีเนื้อหาดังนี้:
ข้อความผิดพลาดจะถูกเก็บไว้ในไฟล์ 'error.log'
สคริปต์จะแยกพารามิเตอร์ของไฟล์กำหนดค่า:
แยกแต่ละบรรทัดกำหนดค่าด้วยช่องว่าง
0: พอร์ตท้องถิ่นเพื่อฟัง
1: พอร์ตท้องถิ่นเพื่อส่งต่อไปยัง
2: ที่อยู่ ip ระยะไกลของเซิร์ฟเวอร์ปลายทาง
3: พอร์ตระยะไกลของเซิร์ฟเวอร์ปลายทาง
และการตั้งค่าย้อนกลับ