不久,張繡聽從謀士賈诩之計,投降曹操,曹操大喜,拜張繡爲揚武将軍,解除了後顧之憂。
建安四年(199年)十二月,曹操自率軍屯于官渡(今中牟北),準備迎擊袁紹。
劉備在陶謙死後,曾一度出任徐州牧,後徐州被呂布攻占,劉備投奔曹操。曹操認爲劉備是個英雄,先後表他爲豫州牧、左将軍。
曹操攻占徐州不久,淮南袁術準備逃往青州往依袁紹,曹操派劉備去截擊,袁術北上不得,嘔血而死。
建安五年(200年)正月,董承等人謀誅曹操事洩,被曹操殺掉。劉備遂襲殺徐州刺史車胄,占據徐州。曹操爲了免于将來同袁紹作戰時前後受敵,決定先消滅在徐州立足未穩的劉備。
當時諸将皆怕袁紹乘機來攻許都,曹操對此胸有成竹,說:“劉備,人傑也,今不擊,必有後患。袁紹雖有大志,而見事遲,必不動也。”
遂進軍,以迅雷不及掩耳之勢擊破劉備,劉備逃奔袁紹。
袁紹是當時北方最強大的一股勢力,也是曹操統一北方最強大的敵人。袁氏一門,自袁紹曾祖袁安以下,“四世居三公位”,“門生故吏遍于天下”,勢力本就很大,後袁紹取得冀、并、幽、青四州之地,實力大增,有軍隊數十萬人。
袁紹以其長子袁譚、次子袁熙、外甥高幹分守青、幽、并三州,後方穩固,兵精糧足,根本不把曹操放在眼裏。他挑選精兵十萬、戰馬萬匹,志在一舉消滅曹操。
建安五年(200年),袁紹命大将顔良等人進兵白馬(今滑縣),自率大軍進屯黎陽(今浚縣東),向曹操發動進攻。
曹操的實力比袁紹弱得多,曹操所占的大河以南地區,地盤既小,又是四戰之地,殘破不堪,還沒有完全恢複,物資比不上袁紹那樣豐富。
曹操的兵力也遠不及袁紹,其總兵力大概不過幾萬人,投入前線的兵力據《武帝紀》說“兵不滿萬,傷者十二三”。
裴松之認爲此數不準确,曹操的兵力不會如此之少,但曹操兵力遠遜于袁紹卻是毫無疑問的。
袁紹大軍來攻,許都震動。曹操安慰衆将說:
“吾知紹之爲人,志大而智小,色厲而膽薄,忌克而少威,兵多而分畫不明,将驕而衆令不一,土地雖廣,糧食雖豐,适足以爲我奉也。”
二月,袁紹大将顔良等人圍攻白馬,拉開了大戰的序幕。四月,曹操親自率兵北上解白馬之圍,他采納謀士荀攸之計,先進軍延津(今延津北一帶),做出要渡河襲擊袁軍的态勢,吸引袁軍分兵西向,然後突然轉向迅速趕往白馬。
曹操軍突然殺到,袁軍措手不及,顔良被關羽斬首,袁軍大敗,白馬之圍遂解。曹操救出白馬軍民,沿黃河西撤。
袁紹聞知,立即命文醜、劉備渡河追趕曹操。曹操見追兵漸近,命軍士解鞍放馬,并置辎重于道。袁軍追兵大至,争搶辎重,陣形混亂。
曹操率領僅有的騎兵突然殺出,大破追兵,陣斬文醜,袁軍大震。曹操初戰得勝,主動撤軍,繼續扼守官渡。
八月,袁紹大軍連營而進,東西數十裏,依沙堆爲屯,進逼官渡,曹操分兵堅守營壘,伺機而動。袁軍向曹營發動猛攻,先是作高橹、起土山,由上向曹營中射箭,接着又挖地道,欲從地下襲擊曹營,皆被曹操以設投石機、挖掘溝壑之法破解。
兩軍一攻一守,相持近二個月,久戰之下,曹操處境極爲困難。十月,袁紹從河北運來糧草萬餘車,派大将淳于瓊等帶萬餘人看守,屯于離袁紹大營四十裏的烏巢。
這時袁紹謀士許攸因向袁紹獻偷襲許都之計不成,且在河北的家眷犯法被抓,心生悔恨,而來投曹操,獻計讓曹操偷襲烏巢。
曹操大喜,跣足出迎,之後親率精銳步騎五千人,軍隊人銜枚,馬勒口,換袁軍軍裝乘夜從小路偷襲烏巢。曹操軍至烏巢,命四面放火,袁軍大亂,淳于瓊拒營死守。
袁紹聞知,急忙派兵救援,曹操左右見“賊騎稍近,請分兵拒之。”
曹操大怒說:“賊在背後,乃白!”
士卒都拼死力戰,因此大破袁軍,斬淳于瓊等,盡燔其糧草。
而當袁紹聽說曹操襲擊烏巢時,認爲這正是攻破曹操大營的好機會,因此派去的援兵很少,而以重兵圍攻曹操大營。
由于曹操預留兵力精且多,曹營未破,烏巢敗訊已經傳來,大将張合、高覽等人率部投降曹操,袁軍潰散,袁紹棄軍逃回黃河以北。
曹軍大獲全勝,斬首七萬餘級,盡獲袁軍辎重圖書珍寶。曹操清點袁紹書信,得到自己部下勾結袁紹的信,盡燒之,說:“當紹之強,孤猶不能自保,而況衆人乎!”
客觀條件上,曹操處于劣勢,但由于他能正确分析客觀條件,善于聽取别人的正确意見,所以能揚長避短,采用正确的戰略戰術,使戰争向有利于自己的方面轉化,經過自己主觀上的努力,終于赢得了勝利。
官渡之戰,曹操擊潰了最大的敵人袁紹,由他統一北方已是大勢所趨。官渡之戰也是中國戰争史上以少勝多、以弱勝強的着名戰例。
建安七年(202年),袁紹病死,袁紹的兩個兒子袁譚、袁尚不和,發生火拼。袁譚不敵袁尚,向曹操乞降。
建安九年(204年)二月,曹操乘袁尚出兵攻打袁譚之機,進軍圍攻邺城(今河北邯鄲臨漳西一帶)。袁尚率軍回救,依滏水(今滏陽河)爲營,曹操進軍将其營寨包圍。
袁尚害怕,請求投降,曹操不許。袁尚乘夜逃跑,袁軍潰散,袁尚逃奔中山(今河北定縣)。曹操命人拿着繳獲袁尚的印绶節钺招降邺城守軍,城中鬥志崩潰,邺城遂被曹操攻破。