Berikut adalah script untuk menyimpan hasil koneksi SSH yang valid ke VALIDSSH.txt dan yang gagal ke BADSSH.txt. Saya juga menambahkan mekanisme lock untuk memastikan penulisan file aman dari race condition saat multiple threads menulis ke file yang sama.

import paramiko
import threading

def check_ssh_connection(ip, username, password, valid_file, bad_file, valid_lock, bad_lock):
    try:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(ip, username=username, password=password)
        result = f"SSH connection successful for {username}@{ip}|{password}\n"
        print(result.strip())
        with valid_lock:
            valid_file.write(result)
        ssh.close()
    except (paramiko.AuthenticationException, paramiko.SSHException) as e:
        result = f"Failed to connect to {username}@{ip}: {str(e)}\n"
        print(result.strip())
        with bad_lock:
            bad_file.write(result)
    except Exception as e:
        result = f"An error occurred for {username}@{ip}: {str(e)}\n"
        print(result.strip())
        with bad_lock:
            bad_file.write(result)

def main():
    valid_file_path = 'VALIDSSH.txt'
    bad_file_path = 'BADSSH.txt'
    
    # Locks untuk memastikan thread-safe file writing
    valid_lock = threading.Lock()
    bad_lock = threading.Lock()

    # Buka kedua file dalam mode append
    with open(valid_file_path, 'a') as valid_file, open(bad_file_path, 'a') as bad_file:
        # Baca IP, username, dan password dari data.txt
        try:
            with open('data.txt', 'r') as ips_file:
                credentials = [line.strip().split('|') for line in ips_file if line.strip()]
        except FileNotFoundError:
            error_msg = "Error: data.txt file not found.\n"
            print(error_msg.strip())
            with bad_lock:
                bad_file.write(error_msg)
            return

        max_connections = 5  # Maximum number of concurrent SSH connections
        threads = []

        for cred in credentials:
            if len(cred) != 3:
                error_msg = f"Invalid credential format: {cred}\n"
                print(error_msg.strip())
                with bad_lock:
                    bad_file.write(error_msg)
                continue
            
            ip, username, password = cred
            t = threading.Thread(target=check_ssh_connection, args=(ip, username, password, valid_file, bad_file, valid_lock, bad_lock))
            threads.append(t)
            t.start()

            # Batasi jumlah koneksi concurrent
            while len(threads) >= max_connections:
                for t in threads:
                    if not t.is_alive():
                        threads.remove(t)
                        break
                if len(threads) >= max_connections:
                    threading.Event().wait(1)

        # Tunggu semua thread selesai
        for t in threads:
            t.join()

if __name__ == "__main__":
    main()

Perubahan utama:

  1. Dua file output: Sekarang script menggunakan VALIDSSH.txt untuk koneksi berhasil dan BADSSH.txt untuk koneksi gagal.
  2. Thread-safe writing: Ditambahkan threading.Lock() untuk mencegah race condition saat multiple threads menulis ke file yang sama.
  3. Simpifikasi: Dihapus argumen command line -o karena filenames sekarang fixed.
  4. Error handling: Semua jenis error (termasuk format invalid dan file tidak ditemukan) akan ditulis ke BADSSH.txt.

Catatan:

  • Script akan membuat file VALIDSSH.txt dan BADSSH.txt jika belum ada.
  • Mode append ('a') digunakan sehingga hasil dari eksekusi sebelumnya tidak terhapus.
  • Untuk menjalankan script, pastikan file data.txt ada dengan format IP|Username|Password per baris.